给定Iterator<Element>,我们如何方便地将该迭代器转换为List<Element>,以便我们可以对其使用List的操作,如get(index), add(Element)等。


当前回答

最好使用像Guava这样的库:

import com.google.common.collect.Lists;

Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);

另一个番石榴的例子:

ImmutableList.copyOf(myIterator);

或Apache Commons Collections:

import org.apache.commons.collections.IteratorUtils;

Iterator<Element> myIterator = ...//some iterator

List<Element> myList = IteratorUtils.toList(myIterator);       

其他回答

List result = new ArrayList();
while (i.hasNext()){
    result.add(i.next());
}

你可以像这样复制一个迭代器到一个新列表:

Iterator<String> iter = list.iterator();
List<String> copy = new ArrayList<String>();
while (iter.hasNext())
    copy.add(iter.next());

这是假设列表中包含字符串。实际上没有更快的方法从迭代器中重新创建列表,您只能手动遍历它,并将每个元素复制到合适类型的新列表中。

编辑:

下面是一个以类型安全的方式将迭代器复制到新列表的泛型方法:

public static <T> List<T> copyIterator(Iterator<T> iter) {
    List<T> copy = new ArrayList<T>();
    while (iter.hasNext())
        copy.add(iter.next());
    return copy;
}

像这样使用它:

List<String> list = Arrays.asList("1", "2", "3");
Iterator<String> iter = list.iterator();
List<String> copy = copyIterator(iter);
System.out.println(copy);
> [1, 2, 3]

在Java 8中,你可以使用添加到Iterator接口的新的forEachRemaining方法:

List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);

你也可以使用来自Apache common -collections的IteratorUtils,尽管它不支持泛型:

List list = IteratorUtils.toList(iterator);

在这种情况下,如果你想要最快的方法,那么for循环会更好。

迭代器运行10,000次的样本量需要40毫秒,而for循环需要2毫秒

        ArrayList<String> alist = new ArrayList<String>();  
        long start, end;  

        for (int i = 0; i < 1000000; i++) {  
            alist.add(String.valueOf(i));  
        }  

        ListIterator<String> it = alist.listIterator();      

        start = System.currentTimeMillis();  
        while (it.hasNext()) {  
            String s = it.next();  
        }  
        end = System.currentTimeMillis();  

        System.out.println("Iterator start: " + start + ", end: " + end + ", delta: "  
            + (end - start));  
        start = System.currentTimeMillis();  
        int ixx = 0;  
        for (int i = 0; i < 100000; i++) {  
            String s = alist.get(i);  
        }  

        System.out.println(ixx);  
        end = System.currentTimeMillis();  
        System.out.println("for loop start: " + start + ", end: " + end + ", delta: "  
            + (end - start));  

这是假设列表中包含字符串。