주요글: 도커 시작하기
반응형
Character 클래스를 이용하여 문자 관련 문제를 좀더 수월하게 처리할 수 있다.

java.lang.Character 클래스

java.lang.Character 클래스는 기본 테이터 타입은 char에 대한 래퍼 클래스(wrapper class)이다. Integer나 Double과 같은 다른 래퍼 클래스와 마찬가지로, Character 클래스는 기본 데이터 타입의 값을 객체 형식으로 표현하기 위해 사용된다. 따라서, Character 클래스를 사용하여 Vector나 ArrayList와 같은 콜렉션 객체에 char 타입을 나타내는 값을 저장할 수 있다. 뿐만 아니라 Character 클래스는 유니코드 캐릭처를 처리할 때 사용되는 몇몇 메소드와 상수값을 제공하고 있다.

먼저 char 타입에 대한 객체 형식으로서 Character 래퍼 클래스를 사용하는 예제를 살펴보자. 다음 예제는 특정의 char 값에 해당하는 Character 객체를 List 객체에 저장하는 것을 보여주고 있다.

import java.util.*;

public class CharDemo1 {
   public static void main(String args[]) {
      List list = new ArrayList();
      
      list.add(new Character('a'));
      list.add(new Character('b'));
      list.add(new Character('c'));
      
      for (int i = 0; i < list.size(); i++) {
         System.out.println(list.get(i));
      }
   }
}

이 예제에서는 글자 'a', 'b', 'c'를 나타내는 세 개의 Character 객체를 List에 추가한 후, List에 저장된 내용을 차례대로 보여주고 있다.

대부분의 래퍼 클래스와 마찬가지로 Character 클래스 역시 유용하게 사용할 수 있는 다양한 메소드를 제공하고 있다. 그러한 메소드에는 isDigit()이나 isSpaceChar()와 같은 것들이 있다. 예를 들어, 사용자가 입력한 글자가 숫자인지를 판단해야 한다고 해보자. Character 클래스를 사용하지 않을 경우 다음과 같은 형태의 코딩을 해야 한다.

char c = ...;
if (c >= '0' && c <= '9') {
    ...
}

이런 형태의 코드가 올바르게 실행되지 않는 것은 아니지만, 문제의 소지가 있다. 예를 들어, 숫자를 표시하는 글자는 단순히 '0' 부터 '9'까지만 존재하는 것이 아니며, 자바는 ASCII 코드가 아닌 유니코드를 사용하기 때문에 이것이 문제가 발생할 수 있다. 예를 들어, 다음 프로그램을 수행해보자.

public class CharDemo2 {
   public static void main(String args[]) {
      int dig_count = 0;
      int def_count = 0;
      
      for (int i = 0; i <= 0xffff; i++) {
         if (Character.isDigit((char)i)) {
            System.out.print( (char)i );
            dig_count++;
         }
         if (Character.isDefined((char)i)) {
            def_count++;
         }
      }
      
      System.out.println("number of digits = " + dig_count);
      System.out.println("number of defined = " + def_count);
   }
}

이 프로그램을 실행하면 dig_count의 값은 159가 된다. 즉, 자바에서는 숫자로 분류되는 글자가 159개가 존재한다는 것이다. 이때 출력되는 글자에는 '0', '1'과 같이 일반적으로 사용되는 글자도 있지만, 그 외에 숫자로 사용되는 글자들도 출력되는 것을 알 수 있다. (여러분이 사용하는 운영체제가 대부분 한글 Windows일 것이기 때문에, '0'부터 '9'이외의 나머지 숫자를 의미하는 글자들은 '?'로 출력될 것이다.) 이 프로그램의 수행 결과중에 한가지 재미있는 사실은 유니 코드의 전체 범위인 65536 개의 글자 중에 47400 개의 글자만이 정의되어 있다는 것을 보여준다는 점이다.

Character 클래스는 isDigit() 뿐만 아니라 이 외에 대소문자 변환을 해 줄 수 있는 toLowerCase() 메소드와 toUpperCase() 메소드를 제공하고 있다. ASCII 코드를 사용할 경우 알파벳 대문자와 알파벳 소문자의 코드는 정확하게 32(0x20) 만큼 차이가 난다. 하지만, 따라서 알파벳 'A'의 소문자를 구하고 싶다면 다음과 같이 하면 된다.

char aUpper = 'A';
char aLower = (char) (aUpper + 32);

하지만, 모든 언어가 알파벳처럼 대소문자의 코드 값이 32 만큼 차이나는 것은 아니다. 다시 한번 말하지만, 자바는 유니코드를 사용하고 있으며, 더욱 확실하게 대소문자 변환을 하고 싶다면 Character 클래스의 toLowerCase() 메소드와 toUpperCase() 메소드를 사용해야 한다. 예를 들어, 알파벳 'A'를 소문자로 변환하고 싶다면 다음과 같이 하면 된다.

char aUpper = 'A';
char aLower = Character.toLowerCase(aUpper);

이렇게 Character.toLowerCase() 메소드를 사용하면, 직접 32 만큼의 숫자를 더해서 소문자를 구하는 것에 비해 코드가 더욱 간결해지며 또한 의미 역시 명확해진다.

Character 클래스는 또한 글자와 정수값 사이에 변환을 해주는 다양한 메소드를 제공하고 있다. 일반적으로 특정한 기수를 사용하는 문자열을 정수로 변환하고자 할 경우 다음과 같이 Integer 클래스의 parseInt() 메소드를 사용한다.

int value = Integer.parseInt("10", 16);

이 경우 value는 16진수 값인 0x10을 값으로 갖게 된다. Character 클래스는 Integer 클래스와 비슷하게 char 값을 다양한 기수에 기반 정수값으로 변환해주는 메소드인 digit() 메소드를 제공하고 있다. 예를 들어, char 값 'b'가 16진수로 처리할 때 정수값이 어떤 정수값을 갖는 지 알고 싶다면 다음과 같이 Character.digit() 메소드를 사용하면 된다.

int dig = Character.digit('b', 16);

여기서 'b'는 16진수값 0x0b에 해당하며, 따라서 dig는 11을 값으로 갖는다. 정수값을 반대로 특정한 기수에 기반한 글자로 변환할 수도 있으며, 이는 forDigit() 메소드를 사용하여 할 수 있다. 예를 들어, 정수값 11을 16진수값으로 변환할 때 어떤 글자에 해당하는 지 알고 싶다면 다음과 같이 하면 된다.

char cdig = Character.forDigit(11, 16);

여기서 cdig는 16진수에서 10진법의 값 11에 해당하는 'b'를 값으로 갖게 된다.

유니코드 캐릭터의 타입을 지정하기 위해서 유니코드 속성 테이블을 사용할 수 있다. 타입은 구두점, 화폐 기호, 글자와 같은 것으로 분류된다. 예를 들어, 화폐 기호를 나타내는 유니코드 캐릭터의 코드 번호를 16진수로 출력하고 싶다면 다음과 같은 프로그램을 실행하면 된다.

public class CharDemo3 {
   public static void main(String args[]) {
      for (int i = 0; i <= 0xffff; i++) {
         if (Character.getType((char)i) == Character.CURRENCY_SYMBOL) {
            System.out.println((char)i + " = " +Integer.toHexString(i));
         }
      }
   }
}

여기서 Character.getType() 메소드는 파라미터로 전달받은 캐릭터의 타입을 구해준다. 카테고리 타입은 Character 클래스의 상수값으로 정의되어 있으니, 자바 API를 참조하기 바란다. CharDemo3를 실행하면 다음과 같은 결과가 출력될 것이다.

$ = 24
? = a2
...
$ = ff04
¢ = ffe0
£ = ffe1
¥ = ffe5
₩ = ffe6

출력 결과를 보면 '$'나 '₩'처럼 화폐 단위를 나타내는 글자가 Character.CURRENCY_SYMBOL 카테고리로 분류된 것을 알 수 있다.

마지막으로 Character 클래스의 이너(inner) 클래스인 Character.UnicodeBlock 클래스에 대해서 살펴보자. Character.UnicodeBlock 클래스는 관련된 글자들을 하나의 블럭으로 묶을 때 사용된다. 이러한 블럭의 종류에는 HANGUL_SYLLABLES, GREEK, ARMENIAN와 같은 것들이 있으며, 블럭의 종류는 Character.UnicodeBlock 클래스에서 상수값으로 정의되어 있다. 예를 들어, 특정 글자가 한글에 속하는 지 살펴보기 위해서는 다음과 같이 하면 된다.

if (Character.UnicodeBlock.of((char)i) 
        == Character.UnicodeBlock.HANGUL_SYLLABLES
  || Character.UnicodeBlock.of((char)i) 
          == Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO ) {
     // 알맞은 처리
}

다음에 있는 CharDemo4 클래스는 실제로 위 코드를 이용하여 모든 한글 글자를 출력해준다.

public class CharDemo4 {
   public static void main(String args[]) {
      for (int i = 0; i <= 0xffff; i++) {
         if (Character.UnicodeBlock.of((char)i) 
                == Character.UnicodeBlock.HANGUL_SYLLABLES
          || Character.UnicodeBlock.of((char)i) 
                == Character.UnicodeBlock.HANGUL_COMPATIBILITY_JAMO ) {
            System.out.print((char)i);
         }
      }
   }
}

결론

Character 클래스는 흔히 문자 처리와 관련된 다양한 기능을 제공해주고 있다. 개발자는 이러한 기능을 사용하여 좀더 편리하게 문자 처리를 할 수 있을 것이다. Character 클래스는 이 글에서 설명한 메소드 이외에도 몇몇 유용한 메소드를 제공하고 있으니 API 문서를 참고하기 바란다.

관련링크:

+ Recent posts