在java中以相反的顺序遍历列表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2102499/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:34:00  来源:igfitidea点击:

Iterating through a list in reverse order in java

javacollections

提问by Allain Lalonde

I'm migrating a piece of code to make use of generics. One argument for doing so is that the for loop is much cleaner than keeping track of indexes, or using an explicit iterator.

我正在迁移一段代码以使用泛型。这样做的一个论点是,for 循环比跟踪索引或使用显式迭代器要干净得多。

In about half the cases, the list (an ArrayList) is being iterated in reverse order by using an index today.

在大约一半的情况下,今天使用索引以相反的顺序迭代列表(一个 ArrayList)。

Can someone suggest a cleaner way of doing this (since I dislike the indexed for loopwhen working with collections), though it does work?

有人可以建议一种更简洁的方法来做到这一点(因为我不喜欢indexed for loop使用集合时的方式),尽管它确实有效?

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

Note:I can't add any new dependencies outside the JDK.

注意:我无法在 JDK 之外添加任何新的依赖项。

采纳答案by John Feminella

Try this:

尝试这个:

// 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());
}

回答by nanda

Create a custom reverseIterable.

创建自定义reverseIterable.

回答by Kevin

Option 1: Have you thought about reversing the List with Collections#reverse()and then using foreach?

选项 1:您是否考虑过使用Collections#reverse()反转 List ,然后使用 foreach?

Of course, you may also want to refactor your code such that the list is ordered correctly so you don't have to reverse it, which uses extra space/time.

当然,您可能还想重构您的代码,以便正确排序列表,这样您就不必反转它,这会占用额外的空间/时间。



EDIT:

编辑:

Option 2: Alternatively, could you use a Dequeinstead of an ArrayList? It will allow you to iterate forwards and backwards

选项 2:或者,您可以使用Deque而不是 ArrayList 吗?它将允许您向前和向后迭代



EDIT:

编辑:

Option 3: As others have suggested, you could write an Iterator that will go through the list in reverse, here is an example:

选项 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);
}

回答by Adamski

I don't think it's possible using the for loop syntax. The only thing I can suggest is to do something like:

我认为不可能使用 for 循环语法。我唯一能建议的是做这样的事情:

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

... but I wouldn't say this is "cleaner" given that it's going to be less efficient.

...但我不会说这是“更干净”,因为它会降低效率。

回答by Adamski

Here is an (untested) implementation of a ReverseIterable. When iterator()is called it creates and returns a private ReverseIteratorimplementation, which simply maps calls to hasNext()to hasPrevious()and calls to next()are mapped to previous(). It means you could iterate over an ArrayListin reverse as follows:

这是ReverseIterable. 当iterator()被调用时,它会创建并返回一个私有ReverseIterator实现,它只是将调用映射到hasNext()tohasPrevious()和调用next()映射到previous()。这意味着您可以ArrayList按如下方式反向迭代:

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

Class Definition

类定义

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()));
  }
}

回答by Allain Lalonde

Also found google collections reversemethod.

还找到了 google collections reverse方法。

回答by tangens

You could use the concrete class LinkedListinstead of the general interface List. Then you have a descendingIteratorfor iterating with the reverse direction.

您可以使用具体类LinkedList而不是通用接口List。然后你有一个descendingIterator反向迭代。

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

Don't know why there is no descendingIteratorwith ArrayList...

不知道为什么没有descendingIteratorArrayList

回答by Ravi Kant Soni

Very simple Example:

非常简单的例子:

List<String> list = new ArrayList<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) {
  ...
}

回答by Ravi Kant Soni

Reason : "Don't know why there is no descendingIterator with ArrayList..."

原因:“不知道为什么没有带有ArrayList的descendingIterator...”

Since array list doesnot keep the list in the same order as data has been added to list. So, never use Arraylist .

由于数组列表不会以与添加到列表中的数据相同的顺序保存列表。所以,永远不要使用 Arraylist 。

Linked list will keep the data in same order of ADD to list.

链表将数据按 ADD 到列表的相同顺序保存。

So , above in my example, i used ArrayList() in order to make user to twist their mind and make them to workout something from their side.

所以,在我上面的例子中,我使用了 ArrayList() 来让用户扭曲他们的想法,让他们从他们身边锻炼一些东西。

Instead of this

而不是这个

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) {
  ...
}

回答by intrepidis

To have code which looks like this:

拥有如下所示的代码:

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

Put this code into a file called "In.java":

将此代码放入名为“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();
                }
            };
        }
    }
}