Pourquoi la classe String en Java n'implémente-t-elle pas itérable?

De nombreuses classes de framework Java implémentent Iterable, mais pas String. Il est logique d'itérer sur des caractères dans un String, tout comme on peut itérer sur des éléments dans un tableau régulier.

Pourquoi String ne pas mettre en œuvre Iterable?

41
demandé sur polygenelubricants 2010-05-05 14:57:08

7 réponses

Il n'y a vraiment pas une bonne réponse. Un itérateur en Java s'applique spécifiquement à une collection d'éléments discrets (objets). On pourrait penser qu'un String, qui implémente CharSequence, devrait être une "collection" de caractères discrets. Au lieu de cela, il est traité comme une seule entité composée de caractères.

En Java, il semble que les itérateurs ne soient vraiment appliqués qu'aux collections et non à une chaîne. Il n'y a aucune raison pour laquelle il est de cette façon (près que je peux dire-vous le feriez probablement parler Gosling ou de l'API écrivains); il semble convention ou d'une décision de conception. En effet, il n'y a rien empêchant CharSequence de la mise en œuvre Iterable.

Cela dit, vous pouvez parcourir les caractères dans une chaîne comme ceci:

for (int i = 0; i < str.length(); i++) {
  System.out.println(str.charAt(i));
}

Ou:

for(char c : str.toCharArray()) {
  System.out.println(c);
}

Ou:

"Java 8".chars().forEach(System.out::println);

Notez également que vous ne pouvez pas modifier un caractère d'une chaîne en place car les chaînes sont immuables. Le compagnon mutable d'une chaîne est StringBuilder (ou l'ancien StringBuffer).

Modifier

Pour clarifier en fonction des commentaires sur cette réponse. J'essaie d'expliquer, une justification possible pourquoi il n'y a pas de Itérateur sur un String. Je n'essaie pas de dire que ce n'est pas possible; en effet, je pense qu'il serait logique que CharSequence implémente Iterable.

String fournit CharSequence, qui, si seulement conceptuellement, est différent d'un String. Un String est généralement considéré comme une seule entité, alors que CharSequence, c'est exactement cela: une séquence des personnages. Il serait judicieux d'avoir un itérateur sur une séquence de caractères (c'est à dire, sur CharSequence), mais pas simplement sur un String lui-même.

Comme Foxfire l'a souligné à juste titre dans les commentaires, String implémente l'interface CharSequence, donc en ce qui concerne le type, a String est un CharSequence. Sémantiquement, il me semble que ce sont deux choses distinctes-je suis probablement pédant ici, mais quand je pense à un String, je le considère généralement comme une entité unique composée de caractères. Envisager l' la différence entre la séquence de chiffres 1, 2, 3, 4 et le nombre 1234. Considérons maintenant la différence entre la chaîne abcd et la séquence de caractères a, b, c, d. Je suis en train de pointer du doigt cette différence.

À mon avis, demander pourquoi String n'a pas d'itérateur, c'est comme demander pourquoi Integer n'a pas d'itérateur afin que vous puissiez itérer sur les chiffres individuels.

22
répondu Vivin Paliath 2016-03-11 17:36:59

La raison est simple: la classe string est beaucoup plus ancienne que itérable.

Et évidemment personne n'a jamais voulu ajouter l'interface à String (ce qui est un peu étrange car il implémente CharSequence qui est basé sur exactement la même idée).

Cependant, il serait quelque peu imperformant car Iterable renvoie un objet . Donc, il devrait envelopper chaque Char retourné.

Edit: tout comme la comparaison:. Net prend en charge l'énumération sur la chaîne, cependant dans. Net Iterable fonctionne également sur les types natifs, donc il n'y a pas d'encapsulation requise comme cela serait nécessaire en Java.

12
répondu Foxfire 2010-05-05 11:53:54

Pour ce que ça vaut, mon collègue Josh Bloch souhaite vivement ajouter cette fonctionnalité à Java 7:

for (char c : aString) { ... }

Et

for (int codePoint : aString) { ... }

Ce serait le moyen le plus simple de faire une boucle sur les caractères et sur les caractères logiques (points de code). Il ne faudrait pas faire String implémenter Iterable, ce qui forcerait la boxe à se produire.

Sans cette fonctionnalité de langue, il n'y aura pas de très bonne réponse à ce problème. Et il semble très optimiste qu'il peut obtenir ce pour arriver, mais je ne suis pas sûr.

10
répondu Kevin Bourrillion 2010-05-05 22:56:58

Ils ont simplement oublié de le faire.

4
répondu akuhn 2010-05-26 10:19:51

L'une des principales raisons pour rendre L'implémentation de chaîne itérable est d'activer la boucle simple pour(chaque), Comme mentionné ci-dessus. Ainsi, une raison pour ne pas rendre L'implémentation de chaîne itérable pourrait être l'inefficacité inhérente d'une implémentation naïve, car elle nécessite de booster le résultat. Cependant, si l'implémentation de L'itérateur résultant (comme retourné par String.iterator()) est final, le compilateur pourrait le cas particulier et générer du code octet sans boxe / unboxing.

2
répondu Hallvard Trætteberg 2010-06-04 07:04:04

Si vous êtes vraiment instrested en itérant ici:

String str = "StackOverflow";

for (char c: str.toCharArray()){
     //here you go
}
1
répondu medopal 2010-05-05 11:04:15

Iterable de quoi? Iterable<Integer> aurait le plus de sens, où chaque élément représente un point de code Unicode. Même {[2] } serait lent et inutile quand nous avons toCharArray.

0
répondu Tom Hawtin - tackline 2010-05-05 11:59:23