7 minute read

이번엔 문자와 문자열 데이터 타입에 대해서 알아보겠습니다.
JAVA 에서 문자는 잘 쓰이진 않지만 문자열은 숫자 자료형과 함께 가장 많이 쓰이는 자료형으로 알고 있습니다.
그래서 이번 포스트에서는 문자 자료형은 간단히 소개만 하고 문자열 자료형에 대해서 집중적으로 다뤄보도록 하겠습니다.

문자 자료형

문자 자료형은 char를 이용하며, char는 글자, 부호 라는 뜻의 character 에서 파생된 것으로 알고 있습니다.
char 자료형을 사용한 예제를 살펴보면 다음과 같습니다.

char a1 = 'a'; // 문자 값 앞 뒤를 인용 부호 ''로 감싸 주어야 합니다.

char 자료형은 JAVA 에서 많이 쓰이진 않는 자료형입니다. 제 기억에 대학교 1, 2학년 때 C를 배우거나 C로 과제를 할 때 많이 썼던 것 같네요 그래도 문자와 관련해서 프로그래밍에선 유니코드, 아스키코드 등을 사용하고 있기 때문에 잘 쓰이지 않는 다곤 해도 기본적인 것은 알고 있어야 합니다.
특히 코드를 보다 보면 char 자료형 변수에 이게 뭐지 하는 값들이 있는 경우가 있는데 그에 대해서 알아보도록 하겠습니다.

다음 코드를 실행해 봅시다.

char a1 = 'a' // 문자로 표현
char a2 = 97 // 아스키코드로 표현
char a3 = '/u0061' // 유니코드로 표현

System.out.println(a1); //a 출력
System.out.println(a2); //a 출력
System.out.println(a3); //a 출력

우리는 한국어를 사용하고 있기 때문에 유니코드에 민감합니다. 특히 옛날 JAVA 코드에서는 현재와 같이 유니코드를 지원하지 않아 위와 같이 char 에 직접 유니코드를 이용한 것들도 심심찮게 볼 수 있습니다.
또한 문자를 숫자로 표현할 수 있는 아스키코드는 문자의 범위를 이용해 어떤 문자는 사용할지 어떤 문자는 사용하지 않을지와 같은 용도로 많이 쓰여서 생각보다 잘 쓰이게 때문에 위 3 가지 예제만 알아두고 가면 좋을 것 같습니다.

문자열 자료형

사람은 언어로 소통하고, 지식을 공유하고 하기 때문에 언어는 사람에게 정말 중요합니다. 그렇기 때문에 프로그래밍에서도 문자열은 정말 중요하다고 볼 수 있습니다.
JAVA 에서는 앞으로 소개해 드리겠지만 String 이라는 문자열 클래스를 이용해 문자열을 처리합니다. 그래서 이번에 다루는 String 에 대해서는 꼼꼼히 살펴 보시길 바랍니다.

문자열

문자열이란 문자로 구성된 문장을 뜻합니다.
JAVA 에서는 문자열을 나타내기 위해 String 을 사용합니다. JAVA 에서 사용하는 String 자료형은 JAVA 에서 제공해 주는 것으로 클래스 자료형입니다.
JAVA 의 String 은 클래스이기 때문에 String 으로 선언된 변수는 무조건 4byte 의 크기를 갖는다는 특징이 있습니다. String 의 예제는 다음과 같습니다.

 번째 방식
String a = "hello world"; // 문자열의 앞과 뒤는 쌍따옴표("") 로 감싸주어야 합니다.

String 은 클래스이기 때문에 다음과 같이 표현할 수도 있습니다.

 번째 방식
String a = new String("hello world");

두 번째 방식은 String 이 클래스라는 특징을 이용해 클래스를 객체로 선언할 때 사용하는 new 를 이용해 변수를 선언하는 방식입니다. 하지만 문자열을 표현할 때는 가급적 첫 번째 방식을 이용하는 것을 추천드립니다.

첫 번째 방식을 추천 드리는 이유는 첫 번째 방식을 리터럴(literal) 표기 방식이라고 합니다. 리터럴 표기 방식은 동일한 리터럴을 사용할 경우 새로운 String 객체를 만들지 않고 기존 것을 사용하기 때문에 모듈 최적화에 용이하기 때문입니다.

원시 자료형의 래퍼 클래스(Wrapper Class)

갑자기 문자와 문자열에 대한 내용을 다루다가 뜬금없이 왜 갑자기 래퍼 클래스지 하실 수 있습니다.
일반적으로 문자열인 String 을 사용하다가 다른 데이터 타입으로 형변환이 필요한 경우가 굉장히 많습니다. 보통 이럴 때 java 에서는 래퍼 클래스를 이용하는데 이러한 이유 때문에 래퍼 클래스에 대해서도 알아보게 되었습니다.

래퍼 클래스(Wrapper Class)란?

보통 int, long, double, float, boolean, char 자료형을 원시(primitive) 자료형이라고 합니다. 이런 원시 자료형들은 String 과는 다르게 클래스, 객체 구조가 아닙니다.
하지만 우리는 프로그래밍을 하다 보면 원시 자료형을 객체로 표현해야 할 때가 있습니다. (ex 보통 문자열은 String 을 다른 타입으로 변환할 때 주로 사용되는 것 같습니다.)
이런 경우를 위해 JAVA 에서는 래퍼 클래스(wrapper class) 를 지원해 줍니다. 각 타입의 래퍼 클래스는 다음과 같습니다.

래퍼 클래스의 구조도

래퍼 클래스의 구조도는 아래 이미지와 같고, 박싱과 언박싱을 이용합니다.

  • 박싱 : 기본타입의 데이터 -> 래퍼 클래스의 인스턴스로 변환하는 과정
  • 언박싱 : 래퍼 클래스의 인스턴스에 저장된 값 -> 기본 타입의 데이터로 꺼내는 과정
//박싱
//Integer 래퍼 클래스 num 에 21의 값을 저장
Integer num = new Integer(21);

//언박싱
//래퍼 클래스 num 의 값을 꺼내 원시 자료형 변수인 n에 저장해 준다.
int n = num.intValue();

JDK 1.5 부터는 박싱과 언박싱이 필요한 상황에 JAVA 컴파일러가 자동으로 처리해주니다.
이런 자동화된 박싱과 언박싱을 오토박싱(AutoBoxing) 과 오토언박싱(AutoUnBoxing) 이라고 부릅니다.

래퍼 클래스를 사용하는 경우

  1. 일반적으로 우리가 자주 사용하는 것은 문자열을 원시 자료형으로 변환하기 위해 사용합니다.

    일반적으로 아래 예시 처럼 사용하며 래퍼 클래스의 형변환 메소드는 valueOf 로 동일합니다.

     String a = "10"
    
     int num = Integer.valueOf(a);
    
  2. 원시 자료형을 Object 로 변환하고자 할 때 사용됩니다.
  3. java.util 패키지의 클래스는 객체만 다루기 때문에 이 때 래퍼 클래스가 사용됩니다.
  4. ArrayList 등과 같은 Collection 프레임 워크의 데이터 구조는 원시 자료형이 아닌 객체만 저장이 되고, 이 때 래퍼 클래스를 이용합니다.

문자열 내장 메소드

String 자료형의 내장 메소드 중에서 자주 사용하는 것을 알아보도록 하겠습니다. String 자료형의 내장 메소드는 문자열 객체에 속한 함수라 할 수 있습니다.
문자열 합치기, 분할, 대소문자 변환 등의 문자열을 다양하게 활용할 수 있도록 도와줍니다.

equals

equals 메소드는 파라매터로 입력을 받은 문자열과 완전히 같은지를 비교하여 true, false 값을 반환합니다.
아마도 JAVA 의 문자열 메소드 중에서 자주 사용되는 메소드 top3 에 들지 않을까 생각될 정도로 굉장히 빈번하게 사용되는 메소드입니다. 그렇기 때문에 꼭 기억을 해주시는게 좋을 듯 합니다.
우리는 보통 같은 타입의 데이터를 비교할 때 == 를 많이 사용합니다만 JAVA 의 String 의 경우 객체이기 때문에 원시 자료형과는 다르게 equals 를 이용해야 정확한 비교가 가능합니다.
그래서 python 을 하다가 JAVA 를 하시는 분들은 문자열 비교를 할 때 == 를 많이 써서 에러가 발생하는 경우가 잦으리라 생각됩니다. 추가적으로 String 변수의 경우 객체이기 때문에 null 과는 비교할 때 == 을 사용해야 합니다.
그럼 예시를 통해 equals 에 대해 자세히 알아보도록 하겠습니다.

equals 를 사용했을 경우

String a = "hello";
String b = "java";
String c = "hello";
System.out.println(a.equals(b)); //false 출력
System.out.println(a.equals(c)); //true 출력

equals 를 사용하지 않을 경우

String a = "hello";
String b = new String("hello");
System.out.println(a.equals(b)); //true
System.out.println(a == b); // false

equals 를 사용하지 않은 예시를 보면 문자열 a 와 b 는 모두 hello 로 값이 같지만 equals 를 호출하면 true 를, == 연산자를 이용하면 false 를 반환합니다. a 와 b 는 값은 같지만 서로 다른 객체이기 때문에 이러한 출력 결과가 나오게 되는 것입니다.
==은 2개의 자료형이 같은 객체인지를 판별할 때 사용하는 연산자이므로 false 를 리턴합니다.

indexOf

indexOf 는 문자열에서 특정 문자열이 시작되는 위치(인덱스 값)를 반환합니다. 문자열 a 에서 Java 가 시작되는 위치를 알고 싶다면 indexOf 를 사용하여 다음처럼 위치를 얻을 수 있습니다.
indexOf 메소드도 굉장히 자주 사용되는 메소드이므로 기억해 주시길 바랍니다.

String a = "Hello Java";
System.out.println(a.indexOf("Java")); // 6출력

결과가 6이 출력되는 이유는 JAVA 에서는 index 와 관련되서는 0부터 세기 때문이며, 좀 더 세세히 알아보기 위해 문자열 a의 각 알파벳에 index 값을 달아보도록 하겠습니다.

H : 0
e : 1
l : 2
l : 3
o : 4
공백 : 5
J : 6
a : 7
v : 8
a : 9

여기서 indexOf 의 입력 값인 Java 가 있는 곳은 6~9 이며 indexOf 는 시작 위치 값을 반환하기 때문에 6이 반환이 됩니다.

contains

contains 메소드는 문자열에서 파라매터로 받은 문자열이 포함되어 있는지에 대한 여부를 리턴합니다. 따라서 결과 값이 boolean 값 입니다.
contains 메소드도 equals 와 함께 가장 많이 사용되는 메소드 중에 하나입니다. 따라서 해당 메소드도 기억해 주셔야 합니다. 예시를 통해 알아보도록 하겠습니다.

String a = "Hello Java";
System.out.println(a.contains("Java")); //출력

문자열 a 에는 Java 라는 문자열을 포함하고 있어 true 를 반환합니다.

charAt

charAt 메소드는 문자열에서 특정 위치의 문자를 반환합니다. 문자열을 자주 사용하게 된다면 이 메소드도 굉장히 자주 사용하게 됩니다.
그리고 이 메소드의 경우 문자열의 특정 index 의 값을 가져오도록 하기 때문에 마구잡이로 사용하게 된다면 ArrayIndexOutOfBoundsExcpetion 에러가 굉장히 많이 뜨기 때문에 사용할 때 신중히 코드의 구성을 생각한 다음에 사용하도록 해야 합니다. 예시를 통해 알아보도록 하겠습니다.

String a = "Hello Java";
System.out.println(a.charAt(6)); // J 출력

replaceAll

replaceAll 메소드는 문자열에서 특정 문자열을 다른 문자열로 바꿀 때 사용합니다. 이 때 바꾸고자 하는 문자열인 첫 번째 파라매터에는 정규표현식이 올 수 있습니다.
이 메소드는 일반적으로 텍스트 데이터를 정제하거나 할 때 사용됩니다.
예시를 통해 알아보도록 하겠습니다.

String a = "Hello Java";
System.out.println(a.replaceAll("Java", "World")); //Hello Java -> Hello World 로 변경됨

substring

substring 메소드는 문자열에서 특정 문자열을 뽑아낼 때 사용합니다. 해당 메소드는 오버로딩 되어 있어 직접 사용하실 때 혼란스러울 수 있는데요 오버로딩 된 것들까지도 한 번 알아보도록 하겠습니다.
substring 은 2가지 메소드로 오버로딩 되어 있습니다.

  • public String substring(int startIndex) : startIndex 부터 끝까지의 문자열을 반환합니다.

    String a = "Hello Java";
    System.out.println(a.substring(6)); //Java 출력
    
  • public String substring(int startIndex, int endIndex) : startIndex 부터 endIndex-1 까지의 문자열을 반환합니다.

    String a = "Hello Java";
    System.out.println(a.subString(6,10))l //Java 출력
    

substring 도 charAt 와 마찬가지로 index 를 이용해 문자열의 특정 부분을 잘라서 가져오는 메소드이기 때문에 ArrayIndexOutOfBoundsExcpetion 에러가 굉장히 빈번하게 뜨도록 하는 메소드입니다.
따라서 charAt 와 마찬가지로 사용하실 때 신중히 로직을 생각한 다음에 해당 메소드를 사용하셔야 합니다.

toUpperCase, toLowerCase

toUpperCase와 toLowerCase 메소드는 문자열을 모두 대문자 혹은 소문자로 변경할 때 사용합니다. 자주 사용되긴 하나 사용법이 간단하고 문자열 작업을 할 때 핵심적으로 사용되는 메소드는 아니라 이런 메소드도 있구나 하시면 될 것 같습니다.
예시는 다음과 같습니다.

String a = "Hello Java";
System.out.println(a.toUpperCase()); //HELLO JAVA 출력
System.out.println(a.toLowerCase()); //hello java 출력

split

split 메소드는 문자열을 특정한 구분자로 나누고, 나눈 문자열들로 이루어진 문자열 배열을 반환해주는 메소드입니다.
문자열에서 특정 부분만 사용하고 싶은데 특정 패턴이 있을 때 사용해서 특정 부분을 가져오도록 해서 사용할 수도 있고, ,, : 등과 같은 특정 기호들로 문자열들이 구분되어 있을 때 기호를 구분자로 하여 나누어서 문자열 배열을 사용하고자 할 때 주로 사용됩니다.
해당 메소드는 JAVA 문자열에서 굉장히 자주 사용되니 꼭 기억해 주시기 바랍니다. 예시는 다음과 같습니다.

String a = "a:b:c:d";
String[] result = a.split(":"); // result 에는 {"a", "b", "c", "d"} 가 담기게 된다

split 메소드에서도 ArrayIndexOutOfBoundsExcpetion 에러가 자주 발생하니 사용할 때 주의해서 사용하도록 합시다.

마치며

이번엔 JAVA 의 문자와 문자열에 대해서 알아보았습니다. 문자열의 경우 대부분 프로그래밍에서 중요하게 사용되기 때문에 필수로 아셔야 하며 JAVA 에서는 C 와 다르게 문자열 객체인 String 을 지원해 주기 때문에 String 에 대해서 꼼꼼히 아시는게 중요할 듯 합니다.
이번에도 포스팅 읽어주셔서 감사드리며 잘못된 내용 혹은 오타, 다른 의견이 있으신 분들은 댓글 남겨주시면 감사하겠습니다.

참조

https://wikidocs.net/261, https://wikidocs.net/205

Tags:

Categories:

Updated:

Comments