Java – Itération sur tous les deux éléments d’une liste

Quel est le meilleur moyen de parcourir une liste tout en traitant 2 éléments en même temps?

Exemple:

List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); for(int i = 0; i  i + 1){ second = ssortingngs.get(i + 1); } System.out.println("First [" + first + "] - Second [" + second + "]"); } 

Résulte en:

 First [item 1] - Second [item 2] First [item 2] - Second [item 3] First [item 3] - Second [item 4] First [item 4] - Second [null] 

J’aimerais réaliser:

 First [item 1] - Second [item 2] First [item 3] - Second [item 4] 

Il suffit d’augmenter i par 2:

 for(int i = 0; i < strings.size(); i += 2) { 

Vous devez modifier et incrémenter i pour la deuxième valeur, modifiez l’instruction:

 second = ssortingngs.get(i + 1); 

à

 second = ssortingngs.get(++i); 

Cela augmentera également le i , puisque cela semble être le comportement souhaité.

Donc, votre code serait:

 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); for(int i = 0; i < strings.size(); i++){ String first = strings.get(i); String second = null; if(strings.size() > i + 1){ second = ssortingngs.get(++i); //Change here } System.out.println("First [" + first + "] - Second [" + second + "]"); } 

J’ai créé la méthode suivante en utilisant un BiConsumer Java8:

 public static  void tupleIterator(Iterable iterable, BiConsumer consumer) { Iterator it = iterable.iterator(); if(!it.hasNext()) return; T first = it.next(); while(it.hasNext()) { T next = it.next(); consumer.accept(first, next); first = next; } } 

utilisez-le comme ceci:

 List myIterable = Arrays.asList("1", "2", "3"); tupleIterator(myIterable, (obj1, obj2) -> { System.out.println(obj1 + " " + obj2); }); 

Cela produira:

 1 2 2 3 

Et si vous augmentiez i de 2 à chaque itération? Devrait faire … Sinon envisager d’augmenter i dans la boucle réelle

Nous devrions bien sûr fournir une solution pour le cas général 😉

 public static void main(Ssortingng[] args) { List list = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }); for (Pair p : Pair.over(list)) { System.out.printf("%d, %d\n", p.first, p.second); } } static class Pair { T first; T second; public Pair(T first, T second) { this.first = first; this.second = second; } public static  Iterable> over(Collection collection) { return new PairWise(collection); } private static class PairWise implements Iterable>, Iterator> { final Iterator iterator; PairWise(Collection collection) { super(); this.iterator = collection.iterator(); } @Override public Iterator> iterator() { return this; } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Pair next() { T first = null; T second = null; if (iterator.hasNext()) first = iterator.next(); else throw new NoSuchElementException(); if (iterator.hasNext()) second = iterator.next(); return new Pair(first, second); } @Override public void remove() { throw new UnsupportedOperationException(); } } } 
 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); int i = 0; for(; i < strings.size() - 1; i+=2){ String first = strings.get(i); String second = strings.get(i + 1); System.out.println("First [" + first + "] - Second [" + second + "]"); } //For odd sized lists if(i < strings.size()){ System.out.println("First [" + strings.get(i) + "]"); } 
 for(int i = 0; i < strings.size(); i++){ String first = strings.get(i++); String second = null; if(strings.size() > i){ second = ssortingngs.get(i); } System.out.println("First [" + first + "] - Second [" + second + "]"); } 
 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); for(int i = 0; i < strings.size(); i++){ if(i½2 = 0){ String first = strings.get(i); System.out.print("First [" + first + "] "); }else{ String second = strings.get(i + 1); System.out.println("- Second [" + second + "]"); } } 

Pour des performances optimales, je vous recommanderai de ne calculer qu’une seule fois la taille de la liste et de ne pas créer de nouvelle chaîne à chaque nouvelle boucle.

 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); int length = ssortingngs.size(); Ssortingng first, second = null; for(int i = 0; i < length; i += 2){ ... } 

Vous pouvez éviter l’indexation avec un Iterator ; cela fonctionne pour n’importe quel Iterable , pas seulement une liste. Obtenez juste un iterator et incrémentez-le deux fois par itération de boucle:

 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); Iterator ssortingngsIterator = ssortingngs.iterator(); while (ssortingngsIterator.hasNext()) { Ssortingng first = ssortingngsIterator.next(); Ssortingng second = ssortingngsIterator.next(); System.out.println("First [" + first + "] - Second [" + second + "]"); } 

Cela suppose une liste de longueur paire et lève NoSuchElementException sur la dernière passe si sa longueur est impaire. Vous pouvez gérer cela de différentes manières:

  • utilisez un trycatch ;
  • avoir une clause de garde qui vérifie que la longueur est même au préalable;
  • vérifiez avant d’obtenir le deuxième élément.

Vérification du deuxième élément:

 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3"); Iterator ssortingngsIterator = ssortingngs.iterator(); while (ssortingngsIterator.hasNext()) { Ssortingng first = ssortingngsIterator.next(); Ssortingng second = ssortingngIterator.hasNext() ? ssortingngIterator.next() : null; System.out.println("First [" + first + "] - Second [" + second + "]"); } 

Les iterators déroutant certaines personnes, vous pouvez donc également utiliser une boucle for-each avec une twig et une variable auxiliaire à bascule pour la parité. C’est bien pire, car la logique de la boucle est beaucoup plus compliquée à simplifier l’itération: au lieu que l’action soit effectuée une fois par tour dans la boucle, en séquence et sans twig, vous devez la parcourir deux fois et mentalement. Notez que ceci saute le dernier élément s’il est de longueur impaire; pourrait ensuite append une vérification de isFirst si vous souhaitez également gérer ces cas.

 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); boolean isFirst = true; Ssortingng first = null; Ssortingng second = null; for (Ssortingng ssortingng : ssortingngs) { if (isFirst) { first = ssortingng; isFirst = false; } else { second = ssortingng; isFirst = true; System.out.println("First [" + first + "] - Second [" + second + "]"); } } 

Enfin, notez que tous ces iterators et variables auxiliaires ont une étendue excessive (ils ne servent que pour la boucle elle-même, ils polluent donc l’environnement local): ils pourraient être encapsulés dans des blocs pour limiter l’étendue, bien que généralement l’imbrication résultante soit prise en compte. pire que la scope excédentaire:

 List ssortingngs = Arrays.asList("item 1", "item 2", "item 3", "item 4"); { Iterator ssortingngsIterator = ssortingngs.iterator(); while (ssortingngsIterator.hasNext()) { Ssortingng first = ssortingngsIterator.next(); Ssortingng second = ssortingngsIterator.next(); System.out.println("First [" + first + "] - Second [" + second + "]"); } } 

Maintenant en Java 8, en utilisant https://github.com/wapatesh/fig

Tu peux écrire:

 seq.forEachSlice(2, (values)->{ // [1,2] [3, 4] });