Java 프로그래밍 - 변수와 자료형

김상윤·2022년 3월 30일
0

변수

변수란? 데이터를 저장하는 메모리 공간에 붙여준 이름이다.

int age = 20;
String country = "Korea"

위와 같은 형식으로 변수를 선언가능하다.
일반화하면,

타입 변수명 = 데이터 ;

위와 같은 형식으로 작성이 가능하다.
자바는 c / c++와 마찬가지로 모든 라인을 마무리 지을경우 ;(세미콜론)을 붙여준다.

변수이름규칙

변수이름규칙이란, 자바에서 변수를 선언할때, 작성하는 변수명에 있어서 지켜야하는 몇가지 규칙들이다.

규칙은 아래와 같다.

문자와 숫자, _ , $ 사용가능
숫자로 시작해서는 안된다.
대소문자를 구분하여, 대문자로 작성된 변수명과 소문자로 작성된 변수명은 서로다른 변수이다.
true, if, continue와 같은 예약어는 사용불가하다.

추가적으로 자바에서는 한글변수명 또한 사용가능하나, 보편적으로는 많이 사용되지 않는다고 한다.

표기법

표기법이란, 반드시 지켜야 하는것은 아니지만, 지킬수록 좋은 것을 의미한다.
대표적인 표기법으로는 카멜표기법, 파스칼 표기법, 스네이크 표기법이 존재한다.

카멜 표기법 (camelCase)

가장 앞의 문자는 소문자로, 나머지 단어의 첫 문자는 대문자로 표기하는 표기법으로써, 마치 낙타의 등과 같은 모양과 같아 카멜 표기법이라 지칭
주로 변수나 함수에 적용한다.
ex) myBag, myShoes

파스칼 표기법 (PascalCase)

각 문자의 첫 문자를 대문자로 표기하는 법
주로 클래스에 적용한다.
ex) MyBag, MyShoes

자료형

자료형이란 변수의 종류와 단위를 표기해주는것이다.
자바에서 표현할 수 있는 대표적인 자료형의 종류는 아래와 같다.

숫자, 부울, 문자, 문자열 등등...

알아두어야 할 점은 변수의 종류에 따라서 담을 수 있는 데이터의 타입 혹은 크기가 서로 상이하다는 것이다.

숫자 자료형

숫자 자료형이란 숫자 형태의 자료형이다.
대표적인 숫자로는 정수,실수, 2진수,8진수,16진수를 예로 들 수 있다.

정수는 int 자료형으로 표현이 가능하다.
ex) int intNum = 10;
만약 더 많은 데이터를 저장하기를 원한다면 long 타입을 사용할 수 있다.

실수는 float, double 자료형으로 표현이 가능하다.
ex) float floatNum = 0.1f; double doubleNum = 3.4028236E38;

2진수

2진수를 나타내기 위해서는 데이터 앞에 0b를 붙여주자
ex) int numBase2 = 0b1100;

8진수

8진수를 표현하기 위해서는 데이터 앞에 0을 붙여주자
ex) int numBase8 = 014;

16진수

16진수를 표현하기 위해서는 데이터앞에 0x를 붙여주자
ex) int numBase16 = 0xC;

코드로 조금 더 자세히 살펴보자

정수

        System.out.println(Integer.MIN_VALUE);
        System.out.println(Integer.MAX_VALUE);

        int intNum2 = Integer.MAX_VALUE + 1;
        System.out.println("intNum2 = " + intNum2);
        long intNum3 = (long)Integer.MAX_VALUE + 1;
        System.out.println("intNum3 = " + intNum3);

위 코드를 실행시키면 아래와 같이 출력된다.

-2147483648
2147483647
intNum2 = -2147483648
intNum3 = 2147483648

하나씩 코드를 해석해보면,

먼저 Integer.MIN_VALUE, Integer.MAX_VALUE를 통해서 int 자료형의 최솟값과 최댓값을 출력해보았다.
그 결과, -2147483648, 2147483647 값이 출력되었다.
즉, int 자료형은 위 범위 안의 숫자들만 표현 가능하다는 것을 알 수 있다.

만약 위 범위를 벗어나는 숫자를 intNum2에 대입하여 출력해보았다.
그 결과 원하지 않는 수가 출력된다.

따라서, int로 표현가능한 범위를 벗어나게 된다면, 원치 않는 잘못된 데이터가 담긴다는 것을 알 수 있고, 이 경우 다른 자료형을 사용해야 한다.

따라서, 이번에는 long 타입으로 intNum3을 선언하고, 해당 값을 다시 대입하여 출력하여보았다.

그 결과 "intNum3 = 2147483648"으로 올바르게 출력되었다.

실수

소스코드

        float floatNum = 1.23f; //마지막에 f를 꼭 붙여줘야지 float로 인식한다.
        double doubleNum = 1.23;
        
        System.out.println("floatNum = " + floatNum);
        System.out.println("doubleNum = " + doubleNum);
        System.out.println(Float.MAX_VALUE);
        System.out.println(Double.MAX_VALUE);

결과

floatNum = 1.23
doubleNum = 1.23
3.4028235E38
1.7976931348623157E308

다음과 같이 각각 float 변수와 double변수를 선언하고 출력해 보았다.
여기서 주의해야 할 점은 float 변수의 경우 데이터 마지막에 f를 꼭 붙여주어야지 float로 인식한다.

float, double의 최댓값을 각각 출력해본결과, 위와 같이 출력되었다.
double의 경우, float보다 더 많은 데이터를 표현할 수 있다는 것을 알 수 있다.

2진수, 8진수, 16진수

        int numBase2 = 0b1100;
        System.out.println("numBase2 = " + numBase2);
        int numBase8 = 014;
        System.out.println("numBase8 = " + numBase8);
        int numBase16 = 0xC;
        System.out.println("numBase16 = " + numBase16);

        //만약 각 진수를 그대로 출력하고 싶을때는?
        System.out.println("0b" + Integer.toBinaryString(numBase2));
        System.out.println("0" + Integer.toOctalString(numBase8));
        System.out.println("0x" + Integer.toHexString(numBase16));
numBase2 = 12
numBase8 = 12
numBase16 = 12
0b1100
014
0xc

정수 12를 위와 같이 서로다른 진수표현으로 나타내보았다.

만약 각 진수를 그대로 출력하고 싶다면,
Integer클래스의 메소드를 통해서 진수 그대로 출력이 가능하다.

부울(Boolean)자료형

부울 자료형이란 참과 거짓을 나타내는 자료형이다.

boolean isPass = true;
boolean isOk = false;

해당 자료형은 주로 조건문에 자주 쓰인다는것을 알수있다.

문자(Character)자료형

문자자료형이란, 한 개의 문자 표현에 사용되는 자료형이다.

char keyFirst = 'a';
char keyLast = 'z';

주의할 점은 문자열의 경우에는 큰따옴표를 사용하나, 문자자료형의 경우에는 작은 따옴표를 사용해주자.

문자열(String)자료형

문자열이란 문자들로 이루어진 집합을 의미한다.
자바에서는 문자열에 해당하는 자료형을 아래와 같이 표기한다.

String s1 = "Hello World!"
String s2 = "01234"

주의해야 할 점은 바로..

문자 단 한개 조차도 문자열이 될 수 있다는 점이다.

문자열 메소드에는 equals,indexOf, replace, substring, toUppercase등 여러가지가 존재한다. 각각에 대해서 살펴보자

equals

equals를 사용하는 아래와 같다.

case 1.

        String s3 = "Hi!";
        String s4 = "H1!";
        System.out.println(s3.equals(s4));
        //출력결과 : true

흔히, equals와 '=='의 기능이 같다고 생각하시는 분들이 종종 있어 해당 내용도 정리를 해보고자 한다.

case 2.

        String s3 = "Hi!";
        String s5 = new String("Hi!");
        System.out.println(s3 == s5);
        System.out.println(s3.equals(s5));
        //출력결과 : false true

위 코드를 실행시키면 출력결과는 아마도 true와 false가 차례대로 출력될 것이다.
case 1, 2를 함께 정리해보면 아래와 같다.

1. equals는 담고있는 값을 비교한다.
2. '=='는 객체를 비교한다.
3. 3가 선언되었을때, Hi! 데이터가 담긴 메모리를 변수명s3로 가리키게 된다.
4. 또, s4가 선언되었고, Hi!를 데이터로 주었다, 이 경우에 s4는 기존 s3가 가리키던 "Hi!"데이터가 담긴 메모리를 똑같이 가리킨다.
5. s5의 경우에는 new String()은 별도의 메모리에 데이터를 새로주어서 새로운 객체를 만드는것이다.
6. 따라서, s3 == s5가 false로 나오게 된다.

따라서, 주로 값을 비교한다면, equals를 사용하자.

indexOf

문자열에서 특정문자열의 위치를 찾아주는데 사용된다.별다른, 시작위치를 주지 않는다면, 처음부터 탐색하며, 가장 처음발견한 인덱스를 리턴한다.

소스코드

String s6 = "Hello! World!";
System.out.println(s6.indexOf("!")); //1

//만약 또 다른 뒤의 인덱스를 리턴받고 싶다면?
System.out.println(s6.indexOf("!", s6.indexOf("!") + 1)); //2

결과

5
12

단순히 느낌표를 찾고 싶어서, Hello! World!기준으로 indexOf를 사용해보았다.
그 결과, 1번과 같이 코드를 작성하면, 가장 처음 발견한 느낌표의 인덱스를 반환한다.
만약 또 다른 뒤의 인덱스를 리턴받고 싶다면? 2번과 같이 fromindex 파라미터를 통해서 어디서부터 인덱스를 찾을건지 지정해줄 수 있다.

replace

replace는 문자열안에서 특정 문자열을 교체한다.

소스코드

String s7 = s6.replace("Hello", "Bye");
System.out.println("s7 = " + s7);

결과

s7 = Bye! World!

replace에는 파라미터로, target,replacement파라미터를 각각 줄 수 있다. target파라미터는 어느 특정 문자열을 바꿀것인지를 선언해주는 것이고, replacement 파라미터는 어느 문자열로 바꿀것인지를 선언해주는 것이다.

substring

substring은 문자열안에서 부분 문자열을 추출해준다.

소스코드

System.out.println(s7.substring(0,3));
System.out.println(s7.substring(0,s7.indexOf("!") + 1));

결과

Bye
Bye!

substring은 추출할 문자열의 시작과 끝을 각각 파라미터로 넣어주면 된다.
indexOf와 같이 사용하면, 더욱 유연하게 작성할 수 있다.

toUpperCase

toUpperCase는 모두 대문자로 변경해준다.

소스코드

String s8 = "bye! world!"
System.out.println(s7.toUpperCase());

결과

BYE! WORLD!

StringBuffer 자료형

StringBuffer는 문자열을 자주 추가하거나 변경할 때 사용하는 자료형이다.
StringBuffer메소드에는 append,insert,substring 등등이 존재한다.

코드를 통해 살펴보자.

소스코드

StringBuffer sb1 = new StringBuffer();
sb1.append("01234");
System.out.println("sb1 = " + sb1);
sb1.append("56789");
System.out.println("sb1 = " + sb1);

결과

sb1 = 01234
sb1 = 0123456789

위와 같은 append기능은 String자료형에서도 비슷하게 구현이 가능하다.

소스코드

String x = "01234";
String y = "56789";

x += y;
System.out.println(x);

결과

0123456789

그러나, 위와 같은 스트링 조작을 자주하는 경우에는 StringBuffer가 훨씬 유리하다.
스트링버퍼는 데이터가 변경되도 객체를 새로 생성하지 않고, 기존의 객체에 이어서 변경한다.
스트링의 경우는 데이터가 변경될 때 마다, 새로운 객체를 생성해서 사용하다보니, 메모리 사용에 있어서 부정적이고, 속도측면에서도 부정적인 결과를 초래한다.

배열(Array)자료형

많은 수의 데이터를 담을 수 있는 자료형이자, 자료구조이다.

타입을 명시한 후에 []를 쓰고, {}사이에 데이터를 콤마로 구분해서 사용한다.
데이터의 개수는 가변적으로 활용가능하다.

소스코드

int[] myArray1 = {1,2,3,4,5};
System.out.println(myArray1[0]);
System.out.println(myArray1[1]);
System.out.println(myArray1[2]);
System.out.println(myArray1[3]);
System.out.println(myArray1[4]);

char[] myArray2 = {'a','b','c','d','e'};
System.out.println(myArray2[0]);

결과

1
2
3
4
5
a

또한,
배열을 만들때, new String으로 특정 개수를 명시한 새로운 객체를 만든뒤,
직접적으로 데이터의 개수를 명시해줄수 있다.

소스코드

String[] myArray3 = new String[3];
myArray3[0] = "Hello";
myArray3[1] = " ";
myArray3[2] = "World";
System.out.println(myArray3[0] + myArray3[1] + myArray3[2]);

출력

Hello World

리스트(List) 자료형

배열과 같이 여러 데이터를 담을 수 있는 자료형이며, 마찬가지로 여러가지 메소드를 제공해준다.

소스코드

ArrayList l1 = new ArrayList();

리스트메소드에는 add,get,size,remove,clear,sort,contains등 여러가지가 존재한다.

add

add는 리스트 자료형에 원소를 더해주는 메소드이다.

소스코드

l1.add(1);
l1.add("Hello");
l1.add(2);
l1.add(3);
l1.add(4);
l1.add("World!");
System.out.println("l1 = " + l1);

출력

l1 = [1, Hello, 2, 3, 4, World!]

add는 또한, 어느위치에 어느데이터를 넣을지 명시해 줄 수도있다.

소스코드

l1.add(0,7);
System.out.println("l1 = " + l1);

출력

l1 = [7, 1, Hello, 2, 3, 4, World!]

get

get은 파라미터로 인덱스를 주어서, 해당 인덱스의 원소를 반환해준다.

소스코드

ArrayList test = new ArrayList();
test.add(1);
System.out.println(test.get(0));

출력

1

size

size는 리스트의 원소의 개수가 몇개인지를 반환해준다.

소스코드

ArrayList test = new ArrayList();
test.add(1);
System.out.println(test.size());

출력

1

remove

remove는 특정 인덱스에 해당하는 원소나, 직접 원소를 지우고 삭제한 원소를 리턴한다.

소스코드

ArrayList test = new ArrayList();
test.add(1);
test.add(2);
test.add(3);
test.add(4);
test.add(5);
test.add(6);
test.add(7);
System.out.println(test.remove(0));
System.out.println("test = " + test);

출력

1
test = [2, 3, 4, 5, 6, 7]

위의 경우에는 test.remove(0)을 통해 0번 인덱스에 해당하는 1을 지우고 1을 반환하였다.

혹은, 인덱스가 아닌 직접 원소를 지우기 위해서는 아래와 같이 작성하자.

소스코드

ArrayList test = new ArrayList();
test.add(1);
test.add(2);
test.add(3);
test.add(4);
test.add(5);
test.add(6);
test.add(7);
System.out.println(test.remove(Integet.valueOf(1));
System.out.println("test = " + test);

출력

true
test = [2, 3, 4, 5, 6, 7]

이 경우에는 삭제가 정상적으로 되었다면, true를 반환한다.

clear

clear는 리스트에 있는 모든 원소를 삭제한다.

소스코드

test.clear();
System.out.println("test = " + test);

출력

test = []

sort

sort는 정렬을 의미한다. 오름차순 또는 내림차순 등으로 정렬이 가능하고, sort의 경우에는 어떻게 정렬할 지를 Comparator를 이용해서 명시해준다.

소스코드

ArrayList l2 = new ArrayList();
l2.add(5);
l2.add(3);
l2.add(4);

l2.sort(Comparator.naturalOrder()); //오름차순
System.out.println("l2 = " + l2);
l2.sort(Comparator.reverseOrder()); //내림차순
System.out.println("l2 = " + l2);

출력

l2 = [3, 4, 5]
l2 = [5, 4, 3]

contains

contains는 데이터가 리스트에 있는지 체크를 해준다.
들어있으면 true, 없으면 false를 리턴해준다.

소스코드

ArrayList l3 = new ArrayList();
l3.add(5);
l3.add(3);
l3.add(4);

System.out.println("l3.contains(1) = " + l3.contains(1));
System.out.println("l3.contains(3) = " + l3.contains(3));

출력

l3.contains(1) = false
l3.contains(3) = true

맵(Map)자료형

파이썬의 dictionary자료형과 유사하며, 키-밸류 형태로 데이터를 저장하는 자료형이다. 제네릭스와 같이 자주 사용하는 자료형이다.

소스코드

HashMap map = new HashMap<>();
map.put("kiwi",9000);
map.put("apple",10000);
map.put("mango",10000);
System.out.println("map = " + map);

출력

map = {apple=10000, kiwi=9000, mango=10000}

map은 put을 통해서 데이터를 삽입가능하다.
키-밸류 형태로 데이터를 저장하므로, put시에는 데이터를 2개 넣어준다.
map의 경우는 put한 순서대로 반드시 데이터가 들어간다고 보장받지 못한다.
결국, 키-밸류 페어로 이루어져있어, 키를 통해 밸류를 접근하면 되기 때문이다.

리스트와 마찬가지로 get을 사용할 수 있다.

소스코드

System.out.println(map.get("mandarin"));
System.out.println(map.get("kiwi"));

출력

null
9000

mandarin의 경우에는 map에 없으므로, null값이 출력되었고, kiwi의 경우에는 9000이라는 밸류에 매핑되어있으므로 9000이 출력된다.

size,remove도 지원한다.

소스코드

System.out.println(map.size());
System.out.println(map.remove("mandarin"));
System.out.println(map.remove("kiwi"));

출력

3
null
9000

map에는 현재 원소가 3개 들어있으므로 3이 출력되었고,
mandarin의 경우에는 현재 map에 속하지 않았으므로 null이 출력되었다.
kiwi의 경우에는 현재 map에 속해있으므로, 해당 밸류값을 리턴하였다.

마지막으로, containskey() 라는것을 지원한다.
containskey()는 키값을 파라미터로 주고, 해당 키가 Map에 존재하는지를 리턴한다.

소스코드

System.out.println(map.containsKey("apple"));
System.out.println(map.containsKey("mandarin"));

출력

true
false

제네릭스(Generics)

자료형을 명시적으로 지정해주는것이다. 제한적일 수 있지만 안정성을 높여줄 수 있다. <>를 통해서 어떤 자료형을 담을지 명시해준다.

소스코드

ArrayList<String> l4 = new ArrayList<String>();
//l4.add(1); //제네릭스로 String을 명시해주었기 때문에, int형은 담을 수 없다.
l4.add("a");
l4.add("Hello");
System.out.println("l4 = " + l4);

출력

l4 = [a, Hello]

ArrayList 뿐만아니라, HashMap에도 적용가능하다.

소스코드

HashMap<String,Integer> map2 = new HashMap<>();
map2.put(123,456); //String이 아니라 Integer라서 에러
map2.put("Hello!","World!"); //Integer가 아니라 String이라서 에러
map2.put("Hello!",123);
System.out.println("map2 = " + map2);

출력

map2 = {Hello!=123}
profile
알고리즘을 아직도 모르겠다

0개의 댓글