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


当前回答

在这种情况下,如果你想要最快的方法,那么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));  

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

其他回答

注意Iterable和Iterator之间是有区别的。

如果你有一个Iterable,那么在Java 8中你可以使用这个解决方案:

Iterable<Element> iterable = createIterable();
List<Element> array = StreamSupport
    .stream(iterable.spliterator(), false)
    .collect(Collectors.toList());

据我所知,collections . tolist()创建ArrayList实例。

其实在我看来,它在一行里也很好看。 例如,如果你需要从某个方法返回List<Element>:

return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());

使用Java .util.stream的纯Java 8非常简洁的解决方案:

public static <T> ArrayList<T> toArrayList(final Iterator<T> iterator) {
    return StreamSupport
        .stream(
            Spliterators
                .spliteratorUnknownSize(iterator, Spliterator.ORDERED), false)
        .collect(
                Collectors.toCollection(ArrayList::new)
    );
}

我只是想指出一个看似显而易见但行不通的解决方案:

List list = Stream.generate(iterator::next)
    .collect(Collectors.toList());

这是因为Stream#generate(Supplier<T>)只能创建无限的流,它并不期望它的参数抛出NoSuchElementException(这就是Iterator#next()最终会做的事情)。

如果你选择迭代器→流→列表的方式,应该使用xehpuk的答案。

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

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