01.JAVA/Java2008. 11. 12. 17:17
반응형
저자 John Zukowski

자바 플랫폼에서의 문자열 정렬은 간단한 작업으로 생각할 수 있으나 국제 시장을 대상으로 한 프로그램을 개발할 경우에는 고려해야 할 사항이 많습니다. 영어만을 기준으로 한다면 tomorrow라는 단어가 today 다음에 정렬되므로 프로그램이 제대로 기능하는 것으로 보이며 아무 문제가 없을지도 모릅니다. 그러나 정렬 기능으로 기본적인 String 클래스의 compare() 메서드만 사용했을 경우 스페인어 사용자가 mañana라는 단어를 정렬하려 한다면 ñ 문자가 z 문자가 다음에 오게 되므로 n 문자와 o 문자 사이의 스페인어 문자 정렬 순서가 틀리게 됩니다. 바로 이러한 문제를 해결하기 위해 java.text 패키지의 Collator 클래스가 사용되는 것입니다.

다음과 같은 단어 목록을 예로 들어 보겠습니다.

  • first
  • mañana
  • man
  • many
  • maxi
  • next

기본 정렬 방법인 String의 클래스의 compare() 메서드를 사용할 경우 위의 단어 목록은 다음과 같이 정렬될 것입니다.

  • first
  • man
  • many
  • maxi
  • mañana
  • next

여기서 mañana는 maxi와 next 사이에 옵니다. 그러나 스페인어 알파벳에서 ñ 문자('에녜'로 발음)는 n 다음에 오므로 mañana는 many와 maxi 사이에 와야 합니다. ñ 문자를 처리하는 정렬 루틴을 자체적으로 만들 수도 있지만, 이번에는 또 독일어 사용자가 독일어 발음 부호를 사용하려 하거나 façade 같은 디자인 패턴 목록을 정렬하려 할 수도 있습니다. 이 경우 façade라는 단어를 factory 앞에 오게 정렬하시겠습니까? 아니면 뒤에 오게 정렬하시겠습니까? 실제로 세디유가 붙은 ç 문자는 c 문자와 동일하게 처리되거나 다르게 처리됩니다.

이러한 문제들을 해결하기 위해 Collator 클래스를 사용할 수 있습니다. Collator 클래스는 언어별 정렬 문제를 고려하므로 ASCII/Unicode 문자 값만을 기준으로 단어를 정렬하지 않습니다. Collator 클래스의 기능과 장점을 제대로 활용하려면 먼저 strength라고 하는 특별한 속성에 대해 잘 알고 있어야 합니다. Collator의 strength 설정은 정렬 순서에 사용되는 비교 정도가 얼마나 강하고 약한지를 결정합니다. 이 속성의 값으로 PRIMARY, SECONDARY, TERTIARY, IDENTICAL이라는 4가지 값을 사용할 수 있습니다. 언어에 대해 이러한 값이 일반적으로 어떻게 작용하는지 알아 보겠습니다. 제일 나중에 언급한 IDENTICAL은 말 그대로 정확하게 같아야만 문자가 동일한 것으로 간주됩니다. TERTIARY는 대소문자를 구분하지 않습니다. SECONDARY는 n에 대해 ñ과 같은 발음 부호의 차이를 무시합니다. PRIMARY는 기본적인 문자 비교 방식은 IDENTICAL과 동일하지만 제어 문자 및 악센트 부호를 처리할 때 몇 가지 차이점이 있습니다. 이러한 차이점과 분석 모드 규칙에 대한 자세한 내용은 Collator javadoc을 참조하십시오.

Collator를 사용하기 위해서는 먼저 한 가지 작업을 수행해야 합니다. 기본 로케일에 대해 getInstance()를 호출하여 사용하거나, 제공된 로케일에 대해 특정 LocalegetInstance() 메서드에 전달하여 사용할 수 있습니다. 예를 들어 스페인어의 경우, 다음과 같이 Locale("es")을 새로 사용하여 스페인어 Locale을 만든 다음 getInstance()에 전달해야 합니다.

 Collator esCollator =
   Collator.getInstance(new Locale("es"));

로케일에 기본 Collator 강도(스페인어에 SECONDARY 값 적용)로도 충분하면 다음과 같이 Comparator와 같은 CollatorCollectionssort() 루틴에 전달하여 정렬된 List를 얻을 수 있습니다.

 Collections.sort(list, esCollator);

이렇게 하면 위의 목록이 스페인어 알파벳의 올바른 순서에 따라 다음과 같이 정렬됩니다.

  • first
  • man
  • many
  • mañana
  • maxi
  • next

Collator에 US 로케일을 사용한다면 영어 알파벳에 ñ이라는 문자가 없기 때문에 mañana가 man과 many 사이에 올 것입니다.

다음은 이러한 차이점을 보여 주는 간단한 예입니다.

import java.awt.*;
import java.text.*;
import java.util.*;
import java.util.List; // Explicit import required
import javax.swing.*;

public class Sort {
 public static void main(String args[]) {
   Runnable runner = new Runnable() {
     public void run() {
       String words[] = {"first", "mañana", "man",
                         "many", "maxi", "next"};
       List list = Arrays.asList(words);
       JFrame frame = new JFrame("Sorting");
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       Box box = Box.createVerticalBox();
       frame.setContentPane(box);
       JLabel label = new JLabel("Word List:");
       box.add(label);
       JTextArea textArea = new JTextArea( list.toString());
       box.add(textArea);
       Collections.sort(list);
       label = new JLabel("Sorted Word List:");
       box.add(label);
       textArea = new JTextArea(list.toString ());
       box.add(textArea);
       Collator esCollator = Collator.getInstance(new Locale("es"));
       Collections.sort(list, esCollator);
       label = new JLabel("Collated Word List:");
       box.add(label);
       textArea = new JTextArea(list.toString());
       box.add(textArea);
       frame.setSize(400, 200);
       frame.setVisible(true);
     }
   };
   EventQueue.invokeLater (runner);
 }
}


sorting

마지막으로 정렬 순서에 대해 알아 둘 내용이 있습니다. getInstance() 호출을 통해 반환된 Collator는 지원되는 언어에 대한 RuleBasedCollator의 인스턴스입니다. RuleBasedCollator를 사용하면 정렬 순서를 원하는 대로 정의할 수 있습니다. 이러한 규칙 구문은 클래스에 대한 javadoc에 자세히 설명되어 있습니다. 여기서는 4자 알파벳을 사용하고 있으며 문자 순서가 ACEF가 아닌 CAFE가 되도록 만드는 규칙을 간단히 예로 들어 보겠습니다.

 String rule =
   "< c, C < a, A < f, F < e, E";
 RuleBasedCollator collator = new RuleBasedCollator(rule);

이 규칙은 대소문자를 표시하여 명시적인 순서를 cafe로 정의합니다. ace, cafe, ef, face라는 단어 목록이 있을 경우 새 규칙을 사용하여 정렬하면 cafe, ace, face, ef 순서가 됩니다.

import java.text.*;
import java.util.*;

public class Rule {
 public static void main(String args[]) throws ParseException {
   String words[] = {"ace", "cafe", "ef", "face"};
   String rule ="< c, C < a, A < f, F < e, E";
   RuleBasedCollator collator = new RuleBasedCollator(rule);
   List list = Arrays.asList(words);
   Collections.sort(list, collator);
   System.out.println(list);
 }
}

컴파일 후 실행하면 새 규칙을 사용하여 정렬된 단어를 볼 수 있습니다.

> javac Rule.java
> java Rule
[cafe, ace, face, ef]

javadoc에서 규칙 구문에 대한 내용을 자세히 읽은 후 더 많은 문자와 다양한 발음 부호를 사용하여 연습해 보십시오.

이제 전 세계를 대상으로 하는 글로벌 프로그램을 개발할 경우 다양한 언어를 지원하는 프로그램을 만들 수 있을 것입니다. 이전 팁에서 설명했듯이 문자열을 리소스 번들에 반드시 포함시켜야 합니다.

이전 팁

*********

사용자 삽입 이미지

GlassFish에 연결하여 참여
GlassFish에 참여하여 iPhone 경품의 주인공이 되어 보십시오. 본 행사는 2008년 3월 23일까지 진행됩니다. 지금 바로 참여하십시오.

Foote on Blu-ray Disc Java 이 비디오 인터뷰에서는 썬의 BDJ(Blu-ray Disc Java) 설계자인 Bill Foote가 강력한 기술에 대해 설명하고 BDJ 코드 및 애플리케이션의 몇 가지 예를 보여 줍니다. 코드 다운로드하기

이 글의 영문 원본은 http://blogs.sun.com/corejavatechtips/e ··· _strings
에서 보실 수 있습니다.

"Java SE" 카테고리의 다른 글


Posted by 1010