提案された回答はいずれも、 Unicode BasicMultiligualPlaneの外部で文字をエンコードするために使用されるサロゲートペアに対しては機能しません。
これは、3つの異なる手法を使用して文字列の「文字」を反復処理する例です(Java 8ストリームAPIの使用を含む)。この例には、Unicode補足多言語面(SMP)の文字が含まれていることに注意してください。この例と結果を正しく表示するには、適切なフォントが必要です。
// String containing characters of the Unicode
// Supplementary Multilingual Plane (SMP)
// In that particular case, hieroglyphs.
String str = "The quick brown jumps over the lazy ";
文字の反復
char
最初の解決策は、すべての文字列に対する単純なループです。
/* 1 */
System.out.println(
"\n\nUsing char iterator (do not work for surrogate pairs !)");
for (int pos = 0; pos < str.length(); ++pos) {
char c = str.charAt(pos);
System.out.printf("%s ", Character.toString(c));
// ^^^^^^^^^^^^^^^^^^^^^
// Convert to String as per OP request
}
コードポイントの反復
2番目のソリューションも明示的なループを使用しますが、 codePointAtを使用して個々のコードポイントにアクセスし、 charCountに応じてループインデックスをインクリメントします。
/* 2 */
System.out.println(
"\n\nUsing Java 1.5 codePointAt(works as expected)");
for (int pos = 0; pos < str.length();) {
int cp = str.codePointAt(pos);
char chars[] = Character.toChars(cp);
// ^^^^^^^^^^^^^^^^^^^^^
// Convert to a `char[]`
// as code points outside the Unicode BMP
// will map to more than one Java `char`
System.out.printf("%s ", new String(chars));
// ^^^^^^^^^^^^^^^^^
// Convert to String as per OP request
pos += Character.charCount(cp);
// ^^^^^^^^^^^^^^^^^^^^^^^
// Increment pos by 1 of more depending
// the number of Java `char` required to
// encode that particular codepoint.
}
StreamAPIを使用してコードポイントを反復処理します
3番目のソリューションは基本的に2番目のソリューションと同じですが、Java 8StreamAPIを使用しています。
/* 3 */
System.out.println(
"\n\nUsing Java 8 stream (works as expected)");
str.codePoints().forEach(
cp -> {
char chars[] = Character.toChars(cp);
// ^^^^^^^^^^^^^^^^^^^^^
// Convert to a `char[]`
// as code points outside the Unicode BMP
// will map to more than one Java `char`
System.out.printf("%s ", new String(chars));
// ^^^^^^^^^^^^^^^^^
// Convert to String as per OP request
});
結果
そのテストプログラムを実行すると、次のようになります。
Using char iterator (do not work for surrogate pairs !)
T h e q u i c k b r o w n ? ? j u m p s o v e r t h e l a z y ? ? ? ? ? ? ? ?
Using Java 1.5 codePointAt(works as expected)
T h e q u i c k b r o w n j u m p s o v e r t h e l a z y
Using Java 8 stream (works as expected)
T h e q u i c k b r o w n j u m p s o v e r t h e l a z y
ご覧のとおり(象形文字を適切に表示できる場合)、最初のソリューションはUnicodeBMP以外の文字を適切に処理しません。一方、他の2つのソリューションは、サロゲートペアをうまく処理します。