我需要使用 Java 以相反的顺序运行列表。

那么它转发到哪里:

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

有没有什么方法可以使用相反的顺序迭代 stringList 对于每个 句法?

为了清楚起见:我知道如何以相反的顺序迭代列表,但想知道(出于好奇)如何在 对于每个 风格。

有帮助吗?

解决方案

在Collections.reverse方法实际上返回与复制到它以相反的顺序原始列表的元素的新列表,因此这与关于原始列表的大小为O(n)的性能。

作为一个更有效的解决方案,可以编写呈现一个列表以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);
}

其他提示

对于列表,您可以使用 谷歌番石榴库:

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

注意 Lists.reverse 反转整个集合,或者做类似的事情 - 它只允许以相反的顺序进行迭代和随机访问。这比先逆向收集效率更高。

要反转任意可迭代对象,您必须读取全部内容,然后向后“重播”它。

(如果你还没有使用它,我会 彻底地 推荐你看看 番石榴. 。这是很棒的东西。)

在列表(不像集)是有序集合,并遍历它确实保留通过合同的顺序。我本来期望一个堆栈以相反的顺序来遍历但遗憾的是它没有。所以,我能想到的最简单的办法是这样的:

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

我认识到,这不是一个“对每个”环溶液。我宁愿使用for循环比引进像谷歌集合了新库。

Collections.reverse()也做的工作,但它更新,而不是在相反的顺序返回副本列表。

这会搞乱与原来的列表,并且还需要在循环外部被调用。 你也不想进行反向每次循环的时间 - 如果应用该Iterables.reverse ideas的人会认为是真实的。

Collections.reverse(stringList);

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

据我所知还没有在标准库标准“reverse_iterator的”之类的事情,支持的for-each这已经是他们带来了晚成语言语法糖语法。

您可以做类似的(项目元素:myList.clone()反()),并支付相应的代价。

这似乎也有不给你方便的方式做昂贵的操作明显的现象相当一致的 - 因为一个列表,顾名思义,可以有O(N)的随机访问的复杂性(你可以实现与单链路的接口),反向迭代可能最终是O(N ^ 2)。当然,如果你有一个ArrayList,你不付出这样的代价。

这可能是一种选择。希望有一种更好的方式来从最后一个元素开始,而不是while循环的结束。

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

作为的评论:你应该能够使用Apache下议院的 ReverseListIterator

Iterable<String> reverse 
    = new IteratorIterable(new ReverseListIterator(stringList));

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

@rogerdpack说,你需要用的ReverseListIterator作为Iterable

不写入一些自定义代码,这将给你的枚举这将扭转元件为您服务。

您应该能够做到这一点在Java中通过创建可迭代的自定义实现,这将在相反的顺序返回元素。

然后,将实例化包装物(或调用该方法,什么具备的,你),其将返回可迭代执行该反转元件在每个循环。

可以使用类别类 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<T> extends ArrayList<T> {
  public ReversibleArrayList(Collection<T> c) { super(c); }
  public Iterable<T> reversed() {
    return new Iterable<T>() {
      public Iterator<T> iterator() {
        return new Iterator<T>() {
          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<String> ral =
      new ReversibleArrayList<String>(
        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
*///:~

绝对是这个问题的迟到答案。一种可能性是在 for 循环中使用 ListIterator。它不像冒号语法那么干净,但它确实有效。

List<String> 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<String> itr = exampleList.listIterator(exampleList.size()); itr.hasPrevious(); /*no-op*/ ) {
    String currentString = itr.previous();
    System.out.println(currentString); 
}

ListIterator 语法的功劳在于 “在 Java 中迭代列表的方法”

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top