web-dev-qa-db-fra.com

Comment appliquer la boucle for-each à chaque caractère d'une chaîne?

Je veux donc itérer pour chaque caractère d'une chaîne.

Donc je pensais:

for (char c : "xyz")

mais j'obtiens une erreur de compilation:

MyClass.Java:20: foreach not applicable to expression type

Comment puis-je faire ceci?

167
Lyndon White

Le moyen le plus simple de rechercher chaque char dans un String consiste à utiliser toCharArray():

for (char ch: "xyz".toCharArray()) {
}

Cela vous donne la concision de chaque construction, mais malheureusement String (qui est immuable) doit effectuer une copie défensive pour générer le char[] (qui est modifiable), ce qui entraîne une pénalité de coût.

De la documentation :

[toCharArray() renvoie] un tableau de caractères nouvellement alloué dont la longueur correspond à la longueur de cette chaîne et dont le contenu est initialisé pour contenir la séquence de caractères représentée. par cette chaîne.

Il existe des méthodes plus verbeuses d'itération sur les caractères d'un tableau (boucle normale, CharacterIterator, etc.), mais si vous êtes prêt à payer le coût toCharArray() pour chaque élément, le plus concis.

304
polygenelubricants
String s = "xyz";
for(int i = 0; i < s.length(); i++)
{
   char c = s.charAt(i);
}

41
Matthew Flaschen

Vous devez convertir l'objet String en un tableau de caractères à l'aide de la méthode toCharArray () de la classe String:

String str = "xyz";
char arr[] = str.toCharArray(); // convert the String object to array of char

// iterate over the array using the for-each loop.       
for(char c: arr){
    System.out.println(c);
}
6
codaddict

En Java 8 , nous pouvons le résoudre comme suit:

String str = "xyz";
str.chars().forEachOrdered(i -> System.out.print((char)i));    

La méthode chars () retourne une IntStream comme mentionné dans doc :

Renvoie un flux de données int prolongeant à zéro les valeurs char de cette séquence. Tout caractère mappé sur un point de code de substitution est transmis sans interprétation. Si la séquence est mutée pendant la lecture du flux, le résultat est indéfini.

Pourquoi utiliser forEachOrdered et non forEach?

Le comportement de forEach est explicitement non déterministe, étant donné que forEachOrdered exécute une action pour chaque élément de ce flux, dans l’ordre de rencontre du flux si le flux a un ordre de rencontre défini. Donc, forEach ne garantit pas que la commande sera conservée. Vérifiez aussi ceci question pour plus.

Nous pourrions aussi utiliser codePoints() pour imprimer, voir ceci réponse pour plus de détails.

4
i_am_zero

Une autre solution utile, vous pouvez utiliser cette chaîne en tant que tableau de chaînes.

for (String s : "xyz".split("")) {
    System.out.println(s);
}
4
kyxap

Si vous utilisez Java 8, vous pouvez utiliser chars() sur un String pour obtenir un Stream de caractères, mais vous devrez convertir le int revenir à char comme chars() renvoie un IntStream.

"xyz".chars().forEach(i -> System.out.print((char)i));

Si vous utilisez Java 8 avec Eclipse Collections , vous pouvez utiliser la méthode CharAdapter class forEach avec une référence lambda ou une méthode pour parcourir l'ensemble des caractères dans un String.

CharAdapter.adapt("xyz").forEach(c -> System.out.print(c));

Cet exemple particulier pourrait également utiliser une référence de méthode.

CharAdapter.adapt("xyz").forEach(System.out::print)

Remarque: je suis un partisan des collections Eclipse.

2
Donald Raab

Vous pouvez également utiliser un lambda dans ce cas.

    String s = "xyz";
    IntStream.range(0, s.length()).forEach(i -> {
        char c = s.charAt(i);
    });
1
ander4y748