web-dev-qa-db-fra.com

Comment obtenir une vue de liste inversée sur une liste en Java?

Je souhaite avoir une vue de liste inversée sur une liste (de la même manière que List#sublist fournit une vue de sous-liste sur une liste). Existe-t-il une fonction qui fournit cette fonctionnalité?

Je ne veux pas faire de copie de la liste ni la modifier.

Ce serait suffisant si je pouvais avoir au moins un itérateur inversé sur une liste dans ce cas cependant.


De plus, je sais comment le mettre en œuvre moi-même. Je demande simplement si Java fournit déjà quelque chose comme ceci.

Mise en œuvre de la démo:

static <T> Iterable<T> iterableReverseList(final List<T> l) {
    return new Iterable<T>() {
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                ListIterator<T> listIter = l.listIterator(l.size());                    
                public boolean hasNext() { return listIter.hasPrevious(); }
                public T next() { return listIter.previous(); }
                public void remove() { listIter.remove(); }                 
            };
        }
    };
}

Je viens de découvrir que certaines implémentations de List ont descendingIterator(), ce dont j'ai besoin. Bien qu'il n'y ait pas de telle implémentation générale pour List. Ce qui est un peu étrange parce que la mise en oeuvre que j'ai vue dans LinkedList est assez générale pour fonctionner avec n'importe quel List.

206
Albert

Guava fournit ceci: Lists.reverse (List)

List<String> letters = ImmutableList.of("a", "b", "c");
List<String> reverseView = Lists.reverse(letters); 
System.out.println(reverseView); // [c, b, a]

Contrairement à Collections.reverse, il s'agit uniquement d'une vue ... elle ne modifie pas l'ordre des éléments dans la liste d'origine. En outre, avec une liste d'origine modifiable, les modifications apportées à la liste d'origine et à la vue sont répercutées dans l'autre.

199
ColinD

Utilisez la méthode .clone () sur votre liste. Il renverra une copie superficielle, ce qui signifie qu'il contiendra des pointeurs sur les mêmes objets, de sorte que vous n'aurez pas à copier la liste. Ensuite, utilisez simplement Collections.

Ergo,

Collections.reverse(list.clone());

Si vous utilisez un List et n'avez pas accès à clone(), vous pouvez utiliser subList() :

List<?> shallowCopy = list.subList(0, list.size());
Collections.reverse(shallowCopy);
204
jcalvert

Si j'ai bien compris, il s'agit d'une ligne de code. Cela a fonctionné pour moi.

 Collections.reverse(yourList);
79
Shakeeb Ayaz

Ce n'est pas vraiment élégant, mais si vous utilisez List.listIterator (int index), vous pouvez obtenir un ListIterator bidirectionnel à la fin de la liste:

//Assume List<String> foo;
ListIterator li = foo.listIterator(foo.size());

while (li.hasPrevious()) {
   String curr = li.previous()
}
33
kkress

Collections.reverse (nums) ... Il inverse en fait l'ordre des éléments. Le code ci-dessous devrait être très apprécié -

List<Integer> nums = new ArrayList<Integer>();
nums.add(61);
nums.add(42);
nums.add(83);
nums.add(94);
nums.add(15);
//Tosort the collections uncomment the below line
//Collections.sort(nums); 

Collections.reverse(nums);

System.out.println(nums);

Sortie: 15,94,83,42,61

13

Je sais que ceci est un ancien post mais aujourd'hui je cherchais quelque chose comme ça. Finalement, j'ai écrit le code moi-même:

private List reverseList(List myList) {
    List invertedList = new ArrayList();
    for (int i = myList.size() - 1; i >= 0; i--) {
        invertedList.add(myList.get(i));
    }
    return invertedList;
}

Non recommandé pour les longues listes, ce n'est pas du tout optimisé. C'est une sorte de solution facile pour les scénarios contrôlés (les listes que je gère ne contiennent pas plus de 100 éléments).

J'espère que ça aide quelqu'un.

4
CocheLee

J'utilise ceci:

public class ReversedView<E> extends AbstractList<E>{

    public static <E> List<E> of(List<E> list) {
        return new ReversedView<>(list);
    }

    private final List<E> backingList;

    private ReversedView(List<E> backingList){
        this.backingList = backingList;
    }

    @Override
    public E get(int i) {
        return backingList.get(backingList.size()-i-1);
    }

    @Override
    public int size() {
        return backingList.size();
    }

}

comme ça:

ReversedView.of(backingList) // is a fully-fledged generic (but read-only) list
4
Museful

Java.util.Deque a descendingIterator() - si votre List est un Deque, vous pouvez l'utiliser.

4
Bozho

Pour les listes de petite taille, nous pouvons créer LinkedList, puis utiliser l’itérateur décroissant comme:

List<String> stringList = new ArrayList<>(Arrays.asList("One", "Two", "Three"));
stringList.stream().collect(Collectors.toCollection(LinkedList::new))
         .descendingIterator().
         forEachRemaining(System.out::println); // Three, Two, One
System.out.println(stringList); // One, Two, Three
1
i_am_zero

Vous pouvez également inverser la position lorsque vous demandez un objet:

Object obj = list.get(list.size() - 1 - position);
1
fede1608

Vous pouvez aussi faire ceci:

static ArrayList<String> reverseReturn(ArrayList<String> alist)
{
   if(alist==null || alist.isEmpty())
   { 
       return null;
   }

   ArrayList<String> rlist = new ArrayList<>(alist);

   Collections.reverse(rlist);
   return rlist;
}
1
jhdrosos