Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at



Java 1.4まではサロゲートペアは考慮されてませんでしたが、1.5になり、サロゲートペアを考慮したAPIが追加されました。そこで、上記テストコードでは1.4系までのAPIと、1.5で追加されたAPIを呼び出してみて、挙動を比べてます。

まず char 型でサロゲートペアを表現してみます。上位サロゲート、下位サロゲートをそれぞれ別のchar型変数として分け、配列に組み込んでます。

char c1 = '\u3042'; // HIRAGANA LETTER A, cp=12354
char c2 = '\uD842'; // tuchi-yoshi (high), cp=134071
char c3 = '\uDFB7'; // tuchi-yoshi (low), cp=134071
char c4 = '\u30D5'; // katakana fu, cp=12501
char c5 = '\u309A'; // handakuten, cp=12442
char c6 = '\uD842'; // kuchi + shichi (high), cp=134047
char c7 = '\uDF9F'; // kuchi + shichi (low), cp=134047
String s = new String(new char[] { c1, c2, c3, c4, c5, c6, c7 });
assertEquals(s, "\u3042\uD842\uDFB7\u30D5\u309A\uD842\uDF9F");

続いてサロゲートペアを考慮しない String.length()String.charAt() を使って文字列をコピーしてみます。最後の assertEquals() を見ると、サロゲートペアが分割された状態の int[] から生成した文字列と一致しています。上位サロゲート・下位サロゲートをそれぞれ独立した一文字として扱い、コピーしている様子が確認できます。

int len = s.length();
assertEquals(len, 7); // ignores surrogate pair :P
int[] actualCps = new int[len];
for (int i = 0; i < len; i++) {
    char c = s.charAt(i);
    actualCps[i] = (int) c;
// Ignores surrogate pairs... :(
// BUT JavaScript unicode escape in browser accepts this format...:(
assertEquals(actualCps, new int[] { 0x3042, 0xD842, 0xDFB7, 0x30D5, 0x309A, 0xD842, 0xDF9F });

今度はサロゲートペアを考慮する String.codePointCount()String.codePointAt() を使ってみます。最後の assertEquals() を見ると、サロゲートペア対象文字をUnicodeコードポイントの16進数で表現した文字列と同じになります。サロゲートペアを1文字としてカウントし、扱えている様子が確認できます。

int countOfCp = s.codePointCount(0, len);
assertEquals(countOfCp, 5); // GOOD.

actualCps = new int[countOfCp];
for (int i = 0, j = 0, cp; i < len; i += Character.charCount(cp)) {
    cp = s.codePointAt(i);
    actualCps[j++] = cp;
// GOOD.
assertEquals(actualCps, new int[] { 0x3042, 0x20BB7, 0x30D5, 0x309A, 0x20B9F });


Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
Help us understand the problem. What are the problem?