Перебор списка в обратном порядке в Java - PullRequest
232 голосов
/ 20 января 2010

Я переношу кусок кода, чтобы использовать дженерики. Один из аргументов для этого заключается в том, что цикл for намного чище, чем отслеживание индексов или использование явного итератора.

Примерно в половине случаев список (ArrayList) итерируется в обратном порядке с использованием индекса сегодня.

Может кто-нибудь предложить более чистый способ сделать это (поскольку мне не нравится indexed for loop при работе с коллекциями), хотя он работает?

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

Примечание: Я не могу добавить новые зависимости вне JDK.

Ответы [ 15 ]

2 голосов
/ 10 марта 2014

Вы можете использовать ReverseListIterator из Apache Commons-Collections:

https://commons.apache.org/proper/commons-collections/javadocs/api-3.2.1/org/apache/commons/collections/iterators/ReverseListIterator.html

2 голосов
/ 09 сентября 2012

Чтобы иметь код, который выглядит так:

List<Item> items;
...
for (Item item : In.reverse(items))
{
    ...
}

Поместите этот код в файл с именем «In.java»:

import java.util.*;

public enum In {;
    public static final <T> Iterable<T> reverse(final List<T> list) {
        return new ListReverseIterable<T>(list);
    }

    class ListReverseIterable<T> implements Iterable<T> {
        private final List<T> mList;

        public ListReverseIterable(final List<T> list) {
            mList = list;
        }

        public Iterator<T> iterator() {
            return new Iterator<T>() {
                final ListIterator<T> it = mList.listIterator(mList.size());

                public boolean hasNext() {
                    return it.hasPrevious();
                }
                public T next() {
                    return it.previous();
                }
                public void remove() {
                    it.remove();
                }
            };
        }
    }
}
2 голосов
/ 20 января 2010

Также найдены Google коллекции обратный метод.

0 голосов
/ 27 мая 2014

Как было предложено по крайней мере дважды, вы можете использовать descendingIterator с Deque, в частности с LinkedList. Если вы хотите использовать цикл for-each (то есть иметь Iterable), вы можете создать и использовать обертку следующим образом:

import java.util.*;

public class Main {

    public static class ReverseIterating<T> implements Iterable<T> {
        private final LinkedList<T> list;

        public ReverseIterating(LinkedList<T> list) {
            this.list = list;
        }

        @Override
        public Iterator<T> iterator() {
            return list.descendingIterator();
        }
    }

    public static void main(String... args) {
        LinkedList<String> list = new LinkedList<String>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");

        for (String s : new ReverseIterating<String>(list)) {
            System.out.println(s);
        }
    }
}
0 голосов
/ 27 июня 2012

Причина: "Не знаю, почему нет никакого убывающего Итератора с ArrayList ..."

Поскольку список массивов не сохраняет список в том же порядке, в котором данные были добавлены в список. Поэтому никогда не используйте Arraylist.

Связанный список будет хранить данные в том же порядке, что и ADD для списка.

Итак, выше, в моем примере, я использовал ArrayList (), чтобы заставить пользователя искажать свои мысли и заставлять тренироваться что-то со своей стороны.

Вместо этого

List<String> list = new ArrayList<String>();

USE:

List<String> list = new LinkedList<String>();

list.add("ravi");

list.add("kant");

list.add("soni");

// Iterate to disply : result will be as ---     ravi kant soni

for (String name : list) {
  ...
}

//Now call this method

Collections.reverse(list);

// iterate and print index wise : result will be as ---     soni kant ravi

for (String name : list) {
  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...