我需要使用Java倒序遍历一个List。
所以这个代码是正向遍历:
for(String string: stringList){
//...do something
}
有没有办法使用 for each 语法以相反的顺序遍历stringList?
为了明确起见:我知道如何按相反顺序迭代列表,但是想知道(出于好奇),如何以 for each 样式执行此操作。
Collections.reverse方法实际上返回了一个包含原始列表中元素的新列表,这些元素是按相反顺序复制到其中的,因此其性能与原始列表的大小成O(n)比例。
作为更有效的解决方案,你可以编写一个装饰器,将List的反向视图呈现为Iterable。装饰器返回的迭代器将使用装饰列表的ListIterator以相反的顺序遍历元素。
例如:
public class Reversed<T> implements Iterable<T> {
private final List<T> original;
public Reversed(List<T> original) {
this.original = original;
}
public Iterator<T> iterator() {
final ListIterator<T> i = original.listIterator(original.size());
return new Iterator<T>() {
public boolean hasNext() { return i.hasPrevious(); }
public T next() { return i.previous(); }
public void remove() { i.remove(); }
};
}
public static <T> Reversed<T> reversed(List<T> original) {
return new Reversed<T>(original);
}
}
你可以这样使用它:
import static Reversed.reversed;
...
List<String> someStrings = getSomeStrings();
for (String s : reversed(someStrings)) {
doSomethingWith(s);
}
你可以使用Google Guava库来处理列表:
for (String item : Lists.reverse(stringList))
{
// ...
}
请注意,Lists.reverse
不会 翻转整个集合或类似的操作——它只允许按相反顺序进行迭代和随机访问,这比先翻转整个集合更有效率。
要翻转任意iterable对象,您需要读取所有内容,然后以相反顺序“重放”。
(如果您还没有使用它,我强烈建议您看一下Guava。它是非常好的东西。)
列表(与集合不同)是一个有序的集合,迭代它会按照契约保留顺序。我本来期望栈可以按照相反的顺序进行迭代,但很遗憾它没有这样做。因此,我能想到的最简单的解决方案是:
for (int i = stack.size() - 1; i >= 0; i--) {
System.out.println(stack.get(i));
}
我意识到这不是“for each”循环的解决方案。我宁愿使用for循环,而不是引入像Google Collections这样的新库。
Collections.reverse()也可以完成任务,但它会更新列表,而不是返回一个以相反顺序排列的副本。
for (int i = stack.size(); i-- >0;) {
- j-hap这将干扰原始列表并且需要在循环外调用。此外,您不希望每次循环都执行反转-如果应用了Iterables.reverse ideas
中的一个,这是否正确?
Collections.reverse(stringList);
for(String string: stringList){
//...do something
}
ReverseListIterator
。Iterable<String> reverse
= new IteratorIterable(new ReverseListIterator(stringList));
for(String string: reverse ){
//...do something
}
正如@rogerdpack所说的那样, 你需要将 ReverseListIterator
包装为一个 Iterable
。
如评论中Roland Nordborg-Løvstad所建议的那样, 在当前Java中可以使用Lambda简化操作。
Iterable<String> reverse = () -> new ReverseListIterator<>(stringList)
public static void main(String[] args) {
List<String> a = new ArrayList<String>();
a.add("1");a.add("2");a.add("3");a.add("4");a.add("5");
ListIterator<String> aIter=a.listIterator();
while(aIter.hasNext()) aIter.next();
for (;aIter.hasPrevious();)
{
String aVal = aIter.previous();
System.out.println(aVal);
}
}
a.listIterator(a.size())
。 - David ConradCollections.reverse(stringList).forEach(str -> ...);
或者使用guava:
Lists.reverse(stringList).forEach(str -> ...);
Set
的集合中是这样。foreach
保证按照从集合的iterator()
方法返回的迭代器的顺序进行迭代。http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html - robertfor row in rows[::-1]
来进行反向迭代。为什么Java没有呢? - Zhou Haibo