Ninguna de las respuestas propuestas trabaja para los pares suplentes utilizados para codificar caracteres fuera del Unicode Basic Multiligual Plane.
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 de Unicode Supplementary Multilingual Plane (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 ";
Iterar de caracteres
La primera solución es un bucle simple a través de toda char
de 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
}
Iterar de puntos de código
La segunda solución utiliza un bucle explícito también, pero accediendo a puntos de código individuales con codePointAt e incrementando el índice de bucle según 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 los puntos de código utilizando el API corriente
La tercera solución es básicamente la misma que la segunda, pero utilizando el 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
});
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 visualizar jeroglíficos correctamente), la primera solución no maneja correctamente los caracteres fuera del Unicode BMP. Por otro lado, las otras dos soluciones se manejan bien con parejas sustitutas.
Esta es una pregunta muy extraña. – user845279
¿Lo es? La respuesta es bastante simple. – ametren
¿Notaste que no quiere un valor 'char'? Y él sabe cómo hacer 'substring()' pero solo quiere una forma más "nítida". FYI, puedo decir que 'substring()' es la mejor manera. – user845279