259 votes

Itération dans une liste dans l’ordre inverse en java

Je suis à la migration d'un morceau de code pour rendre l'utilisation des génériques. Un argument pour le faire, c'est que la boucle est beaucoup plus propre que de garder la trace d'indices, ou de l'utilisation explicite de l'itérateur.

Dans environ la moitié des cas, la liste (une liste de tableaux) est itérée dans l'ordre inverse à l'aide d'un index.

Quelqu'un peut-il suggérer une façon plus propre de le faire (car je n'aime pas le indexés pour la boucle lorsque l'on travaille avec des collections)?

 for (int i = nodes.size() - 1; i >= 0; i--) {
    final Node each = (Node) nodes.get(i);
    ...
 }

Note: je ne peux pas ajouter de nouvelles dépendances à l'extérieur de la JDK.

A pris a accepté de répondre et l'a transformé en:

class ListReverser<T> implements Iterable<T> {
    private ListIterator<T> listIterator;        

    public ListReverser(List<T> wrappedList) {
        this.listIterator = wrappedList.listIterator(wrappedList.size());            
    }               

    public Iterator<T> iterator() {
        return new Iterator<T>() {

            public boolean hasNext() {
                return listIterator.hasPrevious();
            }

            public T next() {
                return listIterator.previous();
            }

            public void remove() {
                listIterator.remove();
            }

        };
    }

}

Qui peut être utilisé comme:

for (final Node each : new ListReverser<Node>(nodes)) {
   //...
}

Pas génial, mais en mieux.

462voto

John Feminella Points 116878

Essaye ça:

 // Substitute appropriate type.
ArrayList<...> a = new ArrayList<...>();

// Add elements to list.

// Generate an iterator. Start just after the last element.
ListIterator li = a.listIterator(a.size());

// Iterate in reverse.
while(li.hasPrevious()) {
  System.out.println(li.previous());
}
 

36voto

Geoffrey Zheng Points 3503

Goyave offre Lists#reverse(List) et ImmutableList#reverse(). Comme dans la plupart des cas, de la Goyave, les anciens délégués à la dernière si l'argument est un ImmutableList, de sorte que vous pouvez utiliser l'ancien, dans tous les cas.

23voto

Adamski Points 29884

Je ne pense pas que c’est possible à l’aide de la syntaxe de la boucle. La seule chose que je peux suggérer est de faire quelque chose comme :

... mais je ne dirais pas c’est plus « propre », étant donné qu’il va s’avérer moins efficace.

15voto

Kevin Points 19613

Avez-vous pensé à l'inversion de la Liste avec les Collections de#reverse() , puis en utilisant foreach?

Bien sûr, vous pouvez également restructurer le code, tels que la liste est ordonnée correctement de sorte que vous n'avez pas à inverser la tendance.


EDIT:

Sinon, pourriez-vous utiliser un Deque au lieu d'une liste de tableaux? Il vous permettra d'effectuer une itération vers l'avant et vers l'arrière


EDIT:

Comme d'autres l'ont suggéré, vous pouvez écrire un Itérateur qui va passer par la liste dans le sens inverse:

import java.util.Iterator;
import java.util.List;

public class ReverseIterator<T> implements Iterator<T>, Iterable<T> {

    private final List<T> list;
    private int position;

    public ReverseIterator(List<T> list) {
        this.list = list;
        this.position = list.size() - 1;
    }

    @Override
    public Iterator<T> iterator() {
        return this;
    }

    @Override
    public boolean hasNext() {
        return position >= 0;
    }

    @Override
    public T next() {
        return list.get(position--);
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException();
    }

}


List<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
list.add("E");

for (String s : new ReverseIterator<String>(list)) {
    System.out.println(s);
}

3voto

nanda Points 12764

Créer un reverseIterable personnalisé

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X