Ни один из предложенных ответов не работает для суррогатных пар, используемых для кодирования символов за пределами базовой мультиязычной плоскости Unicode .
Вот пример, использующий три различных метода для перебора «символов» строки (включая использование потокового API Java 8). Обратите внимание, что этот пример включает символы дополнительной многоязычной плоскости (SMP) Unicode. Вам нужен правильный шрифт, чтобы правильно отобразить этот пример и результат.
// 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
}
Итерация кодовых точек
Второе решение также использует явный цикл, но получает доступ к отдельным кодам с помощью 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.
}
Перебирать кодовые точки с помощью Stream API
Третье решение в основном такое же, как и второе, но с использованием Java 8 Stream API :
/* 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 𓊃 𓍿 𓅓 𓃡
Как вы можете видеть (если вы умеете правильно отображать иероглифы), первое решение не обрабатывает символы должным образом за пределами BMP Unicode. С другой стороны, два других решения хорошо работают с суррогатными парами.