Итерация через список в обратном порядке в Java

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

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

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

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

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

239
задан Tim 18 March 2016 в 05:11
поделиться

7 ответов

Попробуйте это:

// 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());
}
434
ответ дан 23 November 2019 в 03:19
поделиться

Создать пользовательский Организатор .

5
ответ дан 23 November 2019 в 03:19
поделиться

Вот (непроверенная) реализация Организатор . Когда iterator () называется его создает и возвращает частное Реализацию , которое просто отображает звонки hasnext () на () ] и звонки на следующие () сопоставлены на предыдущие () . Это значит, что вы могли бы проиграть по поводу арайлиста в обратном порядке следующим образом:

ArrayList<String> l = ...
for (String s : new ReverseIterable(l)) {
  System.err.println(s);
}

Определение класса

public class ReverseIterable<T> implements Iterable<T> {
  private static class ReverseIterator<T> implements Iterator {
    private final ListIterator<T> it;

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

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

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

  private final ArrayList<T> l;

  public ReverseIterable(ArrayList<T> l) {
    this.l = l;
  }

  public Iterator<T> iterator() {
    return new ReverseIterator(l.listIterator(l.size()));
  }
}
4
ответ дан 23 November 2019 в 03:19
поделиться

также нашел коллекции Google , метод обратного .

2
ответ дан 23 November 2019 в 03:19
поделиться

Вариант 1: Вы думали о обращении списка с коллекциями # обратный () , а затем используя Foreach?

, конечно, вы также можете ревертировать Код такой, что список заказывается правильно, поэтому вам не нужно его отменить, что использует дополнительное пространство / время.


Редактировать:

Вариант 2: В качестве альтернативы, не могли бы вы использовать DECE вместо ArrayList? Это позволит вам передать вперед и назад


Отредактировать:

Вариант 3: Как и другие, вы могли бы написать итератор, который пройдет через список в обратном направлении, вот пример:

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);
}
15
ответ дан 23 November 2019 в 03:19
поделиться

Я не думаю, что это возможно, используя синтаксис для цикла. Единственное, что я могу предложить, - это сделать что-то вроде:

Collections.reverse(list);
for (Object o : list) {
  ...
}

... Но я бы не сказал, что это «уборщик», учитывая, что он будет менее эффективным.

24
ответ дан 23 November 2019 в 03:19
поделиться

Вы могли бы использовать конкретный класс LinkedList вместо общего интерфейса List. Тогда у вас будет descendingIterator для итерации с обратным направлением.

LinkedList<String > linkedList;
for( Iterator<String > it = linkedList.descendingIterator(); it.hasNext(); ) {
    String text = it.next();
}

Не знаю, почему нет descendingIterator с ArrayList...

11
ответ дан 23 November 2019 в 03:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: