2007/05
Javaには文字列の順序付けを変える便利なクラスがあるので紹介します。
package sample; import java.text.CollationKey; import java.text.ParseException; import java.text.RuleBasedCollator; import java.util.Arrays; public class CollatorSample { /** * RuleBasedCollatorで * 数字よりアルファベットが弱い、英大文字より小文字が弱いと判断するルール * を作成し、RuleBasedCollatorを使った文字列の比較、ソート、CollatorKeyを * 使ったソートの結果をStringの文字列比較、ソートの結果を出力し違いを検証 * する。 */ public static void main(String[] args) throws ParseException { //数字よりアルファベットが弱い、英大文字より小文字が弱いと判断するルール String rules = " < a < b < c < d < e < f < g < h < i < j < k < l < m" + " < n < o < p < q < r < s < t < u < v < w < x < y < z" + " < A < B < C < D < E < F < G < H < I < J < K < L < M" + " < N < O < P < Q < R < S < T < U < V < W < X < Y < Z" + " < 0 < 1 < 2 < 3 < 4 < 5 < 6 < 7 < 8 < 9"; RuleBasedCollator collator = new RuleBasedCollator(rules); String s1 = "a"; String s2 = "1"; //作成したルールで比較 System.out.println( "collator.compare(s1, s2)=" + collator.compare(s1, s2)); //Stringで普通に比較 System.out.println("s1.compareTo(s2)=" + s1.compareTo(s2)); //ソート String[] srcArray = { "888RRR", "AAA777", "BBB222", "DDD888", "666ZZZ", "aaa000" }; String[] array1 = new String[srcArray.length]; String[] array2 = new String[srcArray.length]; for (int i = 0; i < srcArray.length; i++) { array1[i] = srcArray[i]; array2[i] = srcArray[i]; } Arrays.sort(array1); //Collator + Arraysでソート。1度の比較ならコスト低 Arrays.sort(array2, collator); printArray(srcArray, "ソート前= "); printArray(array1, "普通にソート= "); printArray(array2, "Collatorでソート= "); //CollatorKey + Arraysでソート //CollatorKeyを作るコストが発生。しかし何度も比較するならコスト低 CollationKey[] collationKeyArray = new CollationKey[srcArray.length]; for (int i = 0; i < srcArray.length; i++) { collationKeyArray[i] = collator.getCollationKey(srcArray[i]); } Arrays.sort(collationKeyArray); printArray(collationKeyArray, "CollationKeyでソート="); } private static void printArray(String[] array, String description) { System.out.print(description + "{"); StringBuffer buf = new StringBuffer(); for (int i = 0; i < array.length; i++) { buf.append(array[i]); buf.append(","); } System.out.println(buf.substring(0, buf.length() - 1) + "}"); } private static void printArray(CollationKey[] array, String description) { System.out.print(description + "{"); StringBuffer buf = new StringBuffer(); for (int i = 0; i < array.length; i++) { buf.append(array[i].getSourceString()); buf.append(","); } System.out.println(buf.substring(0, buf.length() - 1) + "}"); } }
[実行結果]
collator.compare(s1, s2)=-1
s1.compareTo(s2)=48
ソート前= {888RRR,AAA777,BBB222,DDD888,666ZZZ,aaa000}
普通にソート= {666ZZZ,888RRR,AAA777,BBB222,DDD888,aaa000}
Collatorでソート= {aaa000,AAA777,BBB222,DDD888,666ZZZ,888RRR}
CollationKeyでソート={aaa000,AAA777,BBB222,DDD888,666ZZZ,888RRR}
s1.compareTo(s2)=48
ソート前= {888RRR,AAA777,BBB222,DDD888,666ZZZ,aaa000}
普通にソート= {666ZZZ,888RRR,AAA777,BBB222,DDD888,aaa000}
Collatorでソート= {aaa000,AAA777,BBB222,DDD888,666ZZZ,888RRR}
CollationKeyでソート={aaa000,AAA777,BBB222,DDD888,666ZZZ,888RRR}
ルールどおりの比較/ソート結果ですね。
CollatorでソートとCollationKeyでソートは同じ結果になる。
ソートは何度も文字列比較をするから、件数が多いならばCollationKeyを使った方が
いいかもしれない。