Existe-t-il un moyen dans la boucle for-each de Java
for(String s : stringArray) {
doSomethingWith(s);
}
pour savoir à quelle fréquence la boucle a déjà été traitée?
Outre l'utilisation de l'ancienne et bien connue for(int i=0; i < boundary; i++)
boucle, la construction
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
la seule façon d'avoir un tel compteur disponible dans une boucle pour chaque?
Type var = null; for (var : set) dosomething; if (var != null) then ...
Réponses:
Non, mais vous pouvez fournir votre propre comptoir.
La raison en est que le pour-chaque boucle interne ne pas avoir un compteur; il est basé sur l' interface Iterable , c'est-à-dire qu'il utilise un
Iterator
pour parcourir la "collection" - qui peut ne pas être du tout une collection, et peut en fait ne pas être du tout basé sur des index (comme une liste chaînée).la source
for(int idx=0, String s; s : stringArray; ++idx) doSomethingWith(s, idx);
each_with_index
méthode de boucle pourEnumerable
Ruby. Voir apidock.com/ruby/Enumerable/each_with_indexfor
boucle", quelque chose commefor (int i = 0; String s: stringArray; ++i)
Il y a une autre manière.
Étant donné que vous écrivez votre propre
Index
classe et une méthode statique qui renvoie uneIterable
surinstance de cette classe, vous pouvezOù la mise en œuvre de
With.index
quelque chose commela source
La solution la plus simple consiste à exécuter simplement votre propre compteur ainsi:
La raison en est qu'il n'y a aucune garantie réelle que les éléments d'une collection (que cette variante d'
for
itère) ont même un index, ou même un ordre défini (certaines collections peuvent changer l'ordre lorsque vous ajoutez ou supprimez des éléments).Voir par exemple le code suivant:
Lorsque vous exécutez cela, vous pouvez voir quelque chose comme:
indiquant que, à juste titre, l'ordre n'est pas considéré comme une caractéristique saillante d'un ensemble.
Il existe d'autres façons de le faire sans compteur manuel, mais c'est un peu de travail pour des avantages douteux.
la source
L'utilisation de lambdas et d' interfaces fonctionnelles dans Java 8 permet de créer de nouvelles abstractions de boucle. Je peux parcourir une collection avec l'index et la taille de la collection:
Quelles sorties:
Que j'ai implémenté comme:
Les possibilités sont infinies. Par exemple, je crée une abstraction qui utilise une fonction spéciale juste pour le premier élément:
Qui imprime correctement une liste séparée par des virgules:
Que j'ai implémenté comme:
Les bibliothèques commenceront à apparaître pour faire ce genre de choses, ou vous pouvez rouler les vôtres.
la source
Java 8 a introduit la méthode
Iterable#forEach()
/Map#forEach()
, qui est plus efficace pour de nombreuses implémentationsCollection
/Map
par rapport à la boucle "classique" pour chaque boucle. Cependant, dans ce cas également, aucun index n'est fourni. L'astuce consiste à utiliser enAtomicInteger
dehors de l'expression lambda. Remarque: les variables utilisées dans l'expression lambda doivent être effectivement finales, c'est pourquoi nous ne pouvons pas utiliser d'ordinaireint
.la source
Je crains que ce ne soit pas possible avec
foreach
. Mais je peux vous suggérer une simple boucle for-old style :Notez que l' interface List vous donne accès à
it.nextIndex()
.(Éditer)
À votre exemple changé:
la source
L'un des changements
Sun
envisagésJava7
est de fournir un accès auxIterator
boucles internes dans foreach. la syntaxe sera quelque chose comme ça (si cela est accepté):C'est du sucre syntaxique, mais apparemment beaucoup de demandes ont été faites pour cette fonctionnalité. Mais jusqu'à ce qu'il soit approuvé, vous devrez compter les itérations vous-même, ou utiliser une boucle for régulière avec un
Iterator
.la source
Solution idiomatique:
la source
Bien qu'il y ait tellement d'autres moyens mentionnés pour y parvenir, je partagerai mon chemin pour certains utilisateurs insatisfaits. J'utilise la fonction Java 8 IntStream.
1. Tableaux
2. Liste
la source
Si vous avez besoin d'un compteur dans une boucle pour chaque, vous devez vous compter. Il n'y a pas de compteur intégré pour autant que je sache.
la source
Il y a une "variante" à la réponse de pax ... ;-)
la source
i=0; i++;
approche apparemment plus claire ?Pour les situations où je n'ai besoin que de l'index de temps en temps, comme dans une clause catch, j'utilise parfois indexOf.
la source
La meilleure solution optimisée consiste à effectuer les opérations suivantes:
Où Type peut être n'importe quel type de données et types est la variable sur laquelle vous appliquez pour une boucle.
la source
Je suis un peu surpris que personne n'ait suggéré ce qui suit (j'avoue que c'est une approche paresseuse ...); Si stringArray est une liste quelconque, vous pouvez utiliser quelque chose comme stringArray.indexOf (S) pour renvoyer une valeur pour le nombre actuel.
Remarque: cela suppose que les éléments de la liste sont uniques ou peu importe s'ils ne le sont pas (car dans ce cas, il renverra l'index de la première copie trouvée).
Il y a des situations où cela serait suffisant ...
la source
Voici un exemple de la façon dont j'ai fait cela. Cela obtient l'index au niveau de chaque boucle. J'espère que cela t'aides.
la source