Pourquoi ne pas la classe String en Java mettre en œuvre Itératif?
De nombreux framework Java classes implémentent Iterable
, cependant String
ne le fait pas. Il fait sens pour itérer sur les personnages dans un String
, comme on peut itérer sur les éléments dans un tableau normal.
Est-il une raison pourquoi String
ne pas mettre en œuvre Iterable
?
- Considérant que le problème de l'itération à travers la chaîne de caractères char Tableau? (strInput.ToCharArray)
- Tim: String#toCharArray crée un tableau avec une copie de la Chaîne de caractères. Même si elle travaille, elle impose une surcharge inutile juste pour itérer sur les personnages.
Iterator<Character>
serait moins de frais généraux???- En fonction de la situation Iterator<Personnage> pourrait avoir BEAUCOUP moins de frais généraux que toCharArray
- Non, je ne pense pas que c'est raisonnable. Un itérateur optimisé pour générer de longues séquences d'un même personnage?
- Si l'itérateur serait d'utiliser l'autoboxing (par exemple, le Personnage c = 'c'), le code résultant serait d'utiliser des Caractères.valueOf ("c"), qui, selon la Java docs devraient utiliser un cache au lieu de créer de nouvelles instances pour tous les personnages. Dans les Soleils VM, le Caractère instances sont mises en cache pour tous les caractères d'une valeur <= 127.
- Comme je l'ai dit tout dépend de la situation: Si vous avez une longue chaîne et de l'utilisation de l'agent recenseur pour ne recevoir que quelques entrées, ce serait BEAUCOUP mieux. Extrêmes de l'échantillon: E. g. si vous aviez un 1GO de chaîne et utilisé un agent recenseur pour obtenir les 100 premiers caractères de 100 fois, puis votre aurait fondamentalement de 10 000 accède à l'agent recenseur cas, mais lors de l'utilisation de toCharArray vous aurait 100 exemplaires de la chaîne qui, seule, entraîner 5,000,000,000 accès et vous avez encore besoin de l'itération de sorte qu'il serait de 10 000 vs 5,000,010,000. Assez clair de ce qui est mieux, n'est-ce pas (et oui, c'est la construction d'un cas extrême)
Vous devez vous connecter pour publier un commentaire.
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 (des objets). On pourrait penser qu'un
String
, qui met en œuvreCharSequence
, devrait être une "collection" de caractères discrets. Au lieu de cela, il est traité comme une entité unique qui se compose de caractères.En Java, il semble que les itérateurs ne sont réellement appliquées pour les collections, et pas à une chaîne. Il n'ya aucune raison pourquoi il est de cette façon (près que je peux dire - vous aurait 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 la prévention
CharSequence
de la mise en œuvre deIterable
.Cela dit, vous pouvez effectuer une itération sur les caractères dans une chaîne de caractères comme suit:
Ou:
Ou:
Notez également que vous ne pouvez pas modifier un caractère d'une Chaîne en place, car les Chaînes sont immuables. La mutable compagnon de Chaîne est StringBuilder (plus âgés ou StringBuffer).
MODIFIER
À préciser sur la base des commentaires sur cette réponse. J'essaie d'expliquer, une justification possible pour expliquer pourquoi il n'est pas un Itérateur sur un
String
. Je ne suis pas en train de dire qu'il n'est pas possible; en effet, je pense qu'il serait raisonnable pourCharSequence
à mettre en œuvreIterable
.String
fournitCharSequence
, qui, si seulement sur le plan conceptuel, est différent d'unString
. UnString
est généralement considéré comme une seule entité, alors queCharSequence
c'est exactement cela: une séquence de caractères. Il serait judicieux d'avoir un itérateur sur une séquence de caractères (c'est à dire, surCharSequence
), mais pas simplement sur unString
lui-même.Comme Foxfire a à juste titre relevé dans les commentaires,
String
met en œuvre laCharSequence
interface, type sage, unString
est unCharSequence
. Du point de vue sémantique, il me semble que ce sont deux choses séparées - je suis probablement d'être pointilleux, mais quand je pense à uneString
j'ai l'habitude de le penser comme une entité unique qui se compose de caractères. Considérez la différence entre la séquence de chiffres1, 2, 3, 4
et le nombre1234
. Considérons maintenant la différence entre la chaîneabcd
et la séquence de caractèresa, b, c, d
. Je suis en train de pointer du doigt cette différence.À mon avis, de se demander pourquoi
String
ne dispose pas d'un itérateur, c'est comme demander pourquoiInteger
ne dispose pas d'un itérateur de sorte que vous pouvez effectuer une itération sur les chiffres individuels.Iterator
doit agir sur une collection. Infini itérateurs semblent être acceptable dans le bon contexte.String
par lui-même n'est pas unCharSequence
. UnCharSequence
est une séquence de caractères qui est créé à partir d'une Chaîne. Il serait judicieux d'avoir un itérateur sur unCharSequence
mais pas sur leString
lui-même.foreach (char c in s)
en C#, juste magnifique!String
et unCharSequence
sont deux choses distinctes.CharSequence
à mon humble avis (j'ai fait allusion à cela dans ma réponse). Si leCharSequence
interface spécifié un itérateur, je pense que cela aurait plus de sens, plutôt que deString
l'avoir. Merci pour la discussion fructueuse 🙂Iterable<Char>
ne serait pas efficace. Puisque les génériques n'existent qu'au moment de la compilation, Itérable<Char> get compilé vers le bas pourIterable
(ou dans un autre sens,Iterable<Object>
). La création d'une nouvelleChar
pour chaque élément dans la chaîne serait assez ridicule (O(n)
)La raison en est simple: La classe string est beaucoup plus âgé que Itératif.
Et, évidemment, personne n'a jamais voulu ajouter à l'interface de la Chaîne (qui est un peu étrange parce qu'il n'en œuvre CharSequence qui est basé sur exactement la même idée).
Cependant, il serait un peu imperformant parce que Itérable retourne un objet. Donc, il serait nécessaire de placer tous les caractères retournée.
Edit: Juste comme comparaison: .Net prend en charge l'énumération sur la Chaîne, mais dans .Net Itérable fonctionne également sur les types natifs, donc il n'y a pas d'emballage nécessaire, car elle serait requise en Java.
Iterable
(ou de n'importe quel type) àString
comme étant une modification de rupture. Ce n'est pas comme vous pouvez sous-classeString
(dieu merci).Pour ce que ça vaut, mon collègue et Josh Bloch fortement souhaite ajouter cette fonctionnalité à Java 7:
for (char c : aString) { ... }
et
for (int codePoint : aString) { ... }
Ce serait la façon la plus simple de la boucle sur les chars et plus de logique caractères (points de code) jamais. Il ne nécessite pas de prise de
String
mettre en œuvreIterable
, qui aurait la force de boxe à arriver.Sans que le langage, il n'y a pas vraiment de bonne réponse à ce problème. Et il semble très optimiste qu'il peut en tirer que cela arrive, mais je ne suis pas sûr.
CharSequence
plutôt que mis en œuvre pourString
seulement.Ils ont simplement oublié de le faire.
L'une des principales raisons de la Chaîne de mettre en œuvre Itérable est de permettre aux simple pour(chaque) en boucle, comme mentionné ci-dessus. Donc, une raison pour ne pas faire de la Chaîne de mettre en œuvre Itérable pourrait être l'inefficacité de la mise en œuvre d'un naïf, car il nécessite la boxe le résultat. Toutefois, si la mise en œuvre de la Itérateur (tel que retourné par la Chaîne.iterator()) est définitive, le compilateur pourrait spéciales et générer de byte-code gratuit de boxing/unboxing.
Si vous êtes vraiment instrested dans l'itération ici:
Iterable
de quoi?Iterable<Integer>
ferait plus de sens, où chaque élément représente un Unicode codepoint. MêmeIterable<Character>
serait lente et inutile lorsque nous avonstoCharArray
.