将Iterator转换为ArrayList

Mak*_*sim 230 java iterator list arraylist

考虑到Iterator<Element>,我们怎么可以转换IteratorArrayList<Element>(或List<Element>)的最好,最快的可能方式,这样我们就可以使用ArrayList它,例如的操作get(index),add(element)等等.

Ren*_*aud 349

更好地使用像Guava这样的库:

import com.google.common.collect.Lists;

Iterator<Element> myIterator = ... //some iterator
List<Element> myList = Lists.newArrayList(myIterator);
Run Code Online (Sandbox Code Playgroud)

另一个番石榴的例子:

ImmutableList.copyOf(myIterator);
Run Code Online (Sandbox Code Playgroud)

Apache Commons Collections:

import org.apache.commons.collections.IteratorUtils;

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

List<Element> myList = IteratorUtils.toList(myIterator);       
Run Code Online (Sandbox Code Playgroud)

  • @CorayThan少代码+测试方法.虽然我同意你的意见,但我不会仅仅为了使用该方法而添加额外的依赖项.但话说回来,我的大型项目大多使用Guava或Apache Commons ...... (9认同)
  • 我不明白.例如,Guava返回的ArrayList以什么方式比普通的ArrayList更好?他们是否以更有效的方式做到了?即使它更高效,是否真的值得为项目添加额外的依赖(更复杂)? (7认同)
  • 同意Renaud和Stephan.此外,如果您正在使用构建工具,那么包含这些库是世界上最简单的事情......还有......如果您真的不想包含它们,您可以转到Apache/Guava代码的源代码,复制他们在那里所做的事情:FAR比浪费你的时间更好地重新发明已经存在的数百个精心设计和测试的车轮. (4认同)
  • @CorayThan分开征服我的朋友。为什么编写一个库已经提供并经过测试的方法?我们使用了许多Apache Commons和Guava,它们很棒,可以帮助您节省时间和金钱。 (3认同)

Stu*_*rks 225

在Java 8中,您可以使用forEachRemaining已添加到Iterator界面的新方法:

List<Element> list = new ArrayList<>();
iterator.forEachRemaining(list::add);
Run Code Online (Sandbox Code Playgroud)

  • @AquariusPower`::`语法在Java 8中是新的,它引用了一个"方法引用",它是lambda的简写形式.有关详细信息,请参见此处:http://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html (13认同)
  • 这应该是公认的答案,因为它是最短的并且不依赖于第三方库 (4认同)
  • 什么是`::`?它叫什么名字?似乎是对list.add()的直接引用;并且似乎还有一些java8新事物;谢谢!:) (2认同)
  • @javadba最初的问题是关于如何将已有的迭代器转换为新的ArrayList。出于本示例的目的,假设您已经拥有的迭代器称为“iterator”。 (2认同)

Ósc*_*pez 62

您可以将迭代器复制到新列表,如下所示:

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

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

编辑:

这是一种以类型安全的方式将迭代器复制到新列表的通用方法:

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

像这样使用它:

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]
Run Code Online (Sandbox Code Playgroud)


Dub*_*zar 23

注意Iterable和之间有区别Iterator.

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

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

据我所知Collectors.toList()创建ArrayList实例.

实际上在我看来,它在一行中看起来也不错.
例如,如果您需要List<Element>从某个方法返回:

return StreamSupport.stream(iter.spliterator(), false).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

  • 问题是关于Iterator <Element>作为起点,而不是Iterable <Element>. (3认同)

yeg*_*256 21

你也可以使用IteratorUtilsApache commons-collections,虽然它不支持泛型:

List list = IteratorUtils.toList(iterator);
Run Code Online (Sandbox Code Playgroud)


apf*_*ger 8

没有外部依赖,这里是使用 Streams 和 java 16 toList() 的单行代码。

给定一个Iterator<?> iterator

List<?> list = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false).toList();
Run Code Online (Sandbox Code Playgroud)


xeh*_*puk 7

使用普通Java 8的简洁解决方案java.util.stream:

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

  • 我不会称这个解决方案"简洁". (37认同)

小智 7

Iterator中的Java 8 forEachRemaining方法可以在这里使用:

List<Element> elementList = new ArrayList<>(); 
iterator.forEachRemaining(elementList::add);
Run Code Online (Sandbox Code Playgroud)

  • 这正是Stuart Marks的[answer](/sf/answers/1994422671/)所说的,它发表在此答案的两年半之前。 (9认同)

Akv*_*vel 5

List result = new ArrayList();
while (i.hasNext()){
    result.add(i.next());
}
Run Code Online (Sandbox Code Playgroud)

  • @LuggiMendoza:Stack Overflow并不是一个可以剪切和粘贴并解决问题的地方.它意味着提供信息.这是一个非常有用的答案,任何理智的人都应该能够把它放在一起,我是一个迭代器.从它的声音,你几乎没有努力试图了解发生了什么. (11认同)