Можно ли сделать каждый цикл в java в обратном порядке?

Мне нужно запустить список в обратном порядке с помощью Java.

Итак, где это делается вперед:

for(String string: stringList){ //...do something } 

Есть ли способ перебрать stringList в обратном порядке, используя для каждого синтаксиса?

Для ясности: я знаю, как перебирать список в обратном порядке, но хотел бы знать (ради любопытства), как это сделать для каждого стиля.

    Не используйте метод Collections.reverse, который фактически меняет исходный список на месте. Если вы его используете:

    Неправильный способ!

    Collections.reverse(new ArrayList(stringList))

    чтобы избежать изменения оригинала, это возвращает новый список, в котором элементы исходного списка скопированы в него в обратном порядке, и такие требования к производительности и пространству O (n) относятся к размеру исходного списка.

    В качестве более эффективного решения вы можете написать class, который представляет собой обратное представление списка как универсального типа Iterable. Итератор, возвращенный вашим classом, будет использовать ListIterator из украшенного списка для перемещения по элементам в обратном порядке.

    Например:

     public class Reversed implements Iterable { private final List original; public Reversed(List original) { this.original = original; } public Iterator iterator() { final ListIterator i = original.listIterator(original.size()); return new Iterator() { public boolean hasNext() { return i.hasPrevious(); } public T next() { return i.previous(); } public void remove() { i.remove(); } }; } public static  Reversed reversed(List original) { return new Reversed(original); } } 

    И вы бы использовали его как:

     import static Reversed.reversed; ... List someStrings = getSomeStrings(); for (String s : reversed(someStrings)) { doSomethingWith(s); } 

    Для получения списка вы можете использовать библиотеку Google Guava :

     for (String item : Lists.reverse(stringList)) { // ... } 

    Обратите внимание, что Lists.reverse не Lists.reverse весь сбор или не делает ничего подобного – он просто разрешает итерацию и произвольный доступ в обратном порядке. Это более эффективно, чем обратная assembly.

    Чтобы обратить вспять произвольное итерируемое, вам придется прочитать все, а затем «переиграть» его назад.

    (Если вы еще не используете его, я бы порекомендовал вам взглянуть на Гуаву . Это здорово.)

    Список (в отличие от набора) представляет собой упорядоченную коллекцию и итерацию по ней сохраняет заказ по контракту. Я бы ожидал, что Stack будет итератировать в обратном порядке, но, к сожалению, это не так. Поэтому самое простое решение, о котором я могу думать, следующее:

     for (int i = stack.size() - 1; i >= 0; i--) { System.out.println(stack.get(i)); } 

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

    Collections.reverse () также выполняет задание, но он обновляет список, а не возвращает копию в обратном порядке.

    Это будет бесполезно с исходным списком и также должно быть вызвано вне цикла. Кроме того, вы не хотите выполнять обратное при каждом цикле – это было бы верно, если бы применялась одна из Iterables.reverse ideas ?

     Collections.reverse(stringList); for(String string: stringList){ //...do something } 

    AFAIK в стандартной библиотеке не существует стандартного типа «reverse_iterator», который поддерживает синтаксис for-each, который уже является синтаксическим сахаром, который они заподозрили на языке.

    Вы можете сделать что-то вроде (элемент Item: myList.clone (). Reverse ()) и оплатить соответствующую цену.

    Это также кажется вполне согласующимся с очевидным явлением, которое не дает вам удобных способов выполнения дорогостоящих операций – поскольку список по определению может иметь сложность произвольного доступа O (N) (вы можете реализовать интерфейс с помощью одной ссылки), наоборот итерация может оказаться O (N ^ 2). Конечно, если у вас есть ArrayList, вы не платите эту цену.

    Это может быть вариант. Надеюсь, что есть лучший способ начать с последнего элемента, чем до цикла while.

     public static void main(String[] args) { List a = new ArrayList(); a.add("1");a.add("2");a.add("3");a.add("4");a.add("5"); ListIterator aIter=a.listIterator(); while(aIter.hasNext()) aIter.next(); for (;aIter.hasPrevious();) { String aVal = aIter.previous(); System.out.println(aVal); } } 

    По состоянию на комментарий : вы должны иметь возможность использовать Apache Commons ReverseListIterator

     Iterable reverse = new IteratorIterable(new ReverseListIterator(stringList)); for(String string: reverse ){ //...do something } 

    Как сказал @rogerdpack , вам нужно обернуть ReverseListIterator как Iterable .

    Не забудьте написать какой-то пользовательский код, который даст вам перечислитель, который изменит вам элементы.

    Вы должны иметь возможность сделать это на Java, создав пользовательскую реализацию Iterable, которая вернет элементы в обратном порядке.

    Затем вы должны создать экземпляр оболочки (или вызвать метод, what-have-you), который будет возвращать реализацию Iterable, которая меняет элемент в каждом цикле.

    Вы можете использовать class Collections http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html, чтобы отменить список, затем цикл.

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

    Все вышеприведенные ответы удовлетворяют только требованию, либо путем переноса другого метода, либо вызова внешнего кода за пределами;

    Вот решение, скопированное из четвертого издания « Мышление в Java» , глава 11.13.1 AdapterMethodIdiom ;

    Вот код:

     // The "Adapter Method" idiom allows you to use foreach // with additional kinds of Iterables. package holding; import java.util.*; @SuppressWarnings("serial") class ReversibleArrayList extends ArrayList { public ReversibleArrayList(Collection c) { super(c); } public Iterable reversed() { return new Iterable() { public Iterator iterator() { return new Iterator() { int current = size() - 1; //why this.size() or super.size() wrong? public boolean hasNext() { return current > -1; } public T next() { return get(current--); } public void remove() { // Not implemented throw new UnsupportedOperationException(); } }; } }; } } public class AdapterMethodIdiom { public static void main(String[] args) { ReversibleArrayList ral = new ReversibleArrayList( Arrays.asList("To be or not to be".split(" "))); // Grabs the ordinary iterator via iterator(): for(String s : ral) System.out.print(s + " "); System.out.println(); // Hand it the Iterable of your choice for(String s : ral.reversed()) System.out.print(s + " "); } } /* Output: To be or not to be be to not or be To *///:~ 

    Определенно поздний ответ на этот вопрос. Одна из возможностей – использовать ListIterator в цикле for. Это не так чисто, как синтаксис двоеточия, но он работает.

     List exampleList = new ArrayList<>(); exampleList.add("One"); exampleList.add("Two"); exampleList.add("Three"); //Forward iteration for (String currentString : exampleList) { System.out.println(currentString); } //Reverse iteration for (ListIterator itr = exampleList.listIterator(exampleList.size()); itr.hasPrevious(); /*no-op*/ ) { String currentString = itr.previous(); System.out.println(currentString); } 

    Кредит для синтаксиса ListIterator переходит в «Способы перебора списка в Java»

    Давайте будем гением компьютера.