给定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);       

其他回答

最好使用像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);       

试试Cactoos的StickyList:

List<String> list = new StickyList<>(iterable);

免责声明:我是开发者之一。

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

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

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

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

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

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

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