自分の頭を整理するために書いておく。正しいかは知らない。
まず前提として、Javaの内部表現としての「文字」は16ビット長のUTF-16ということがある。そうすると、普通に長さを取得すると、UTF-16のサロゲートペアで表される文字は2文字と扱われる。
また、文字には合成済み文字という話がある。「か」の後に濁点を結合することで、「が」を表現するみたいなやつ。
これらから、どこまで考慮して文字列の長さを取得するかでやり方が違う。
以下試したサンプルコード。
import java.text.BreakIterator; public class UnicodeCharSample { public static void main(String[] args) { // 𪛀あが String s = "\uD869\uDEC0あか\u3099"; // UTF-16のサロゲートペアを考慮しない // 5文字と判定 System.out.println(s.length()); // UTF-16のサロゲートペアを考慮する // 4文字と判定 System.out.println(s.codePointCount(0, s.length())); // 合成済み文字を考慮する BreakIterator bi = BreakIterator.getCharacterInstance(); bi.setText(s); int length = 0; while (bi.next() != BreakIterator.DONE) { length++; } // 3文字と判定 System.out.println(length); } }