Ninguna de las respuestas propuestas funciona para pares sustitutos utilizados para codificar caracteres fuera del plano multiligual básico Unicode .
Aquí hay un ejemplo que usa tres técnicas diferentes para iterar sobre los "caracteres" de una cadena (incluido el uso de Java 8 stream API). Tenga en cuenta que este ejemplo incluye caracteres del Plano multilingüe suplementario Unicode (SMP). Necesita una fuente adecuada para mostrar este ejemplo y el resultado correctamente.
// String containing characters of the Unicode
// Supplementary Multilingual Plane (SMP)
// In that particular case, hieroglyphs.
String str = "The quick brown 𓃥 jumps over the lazy 𓊃𓍿𓅓𓃡";
Iteración de caracteres
La primera solución es un bucle simple sobre toda char
la cadena:
/* 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
}
Iteración de puntos de código
La segunda solución también usa un bucle explícito, pero accede a puntos de código individuales con codePointAt e incrementa el índice del bucle de acuerdo con 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.
}
Iterar sobre puntos de código usando la API Stream
La tercera solución es básicamente la misma que la segunda, pero con la API Java 8 Stream :
/* 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
});
Resultados
Cuando ejecuta ese programa de prueba, obtiene:
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 𓊃 𓍿 𓅓 𓃡
Como puede ver (si puede mostrar los jeroglíficos correctamente), la primera solución no maneja correctamente los caracteres fuera del BMP de Unicode. Por otro lado, las otras dos soluciones tratan bien con pares sustitutos.