java list转iterable - 将Iterator转换为ArrayList





java用法 (11)


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

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

给定Iterator<Element> ,我们如何以最佳和最快的方式将Iterator转换为ArrayList<Element> (或List<Element> ),以便我们可以使用ArrayList的操作,比如get(index) add(element)







用java 8你可以使用这个解决方案:

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

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

其实在我看来,它看起来还不错。
例如,如果您需要从某种方法返回List<Element>

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



更好地使用像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

Iterable<String> fieldsIterable = ...
List<String> fields = Lists.newArrayList(fieldsIterable);

++




在这种情况下,如果你想要最快的方式,那么for loop更好。

对于10,000 runs的样本量,迭代器需要40 ms ,for循环需要2 ms

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

假设列表包含字符串。




我只想指出一个看起来很明显的解决方案,它不起作用:

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

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

如果Iterator→Stream→List方式是您的选择,则应该使用share 。




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



Cactoos尝试StickyList

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

免责声明:我是其中一位开发人员。




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

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



另一个,适用于所有Spring用户:

import java.nio.charset.StandardCharsets;
import org.springframework.util.FileCopyUtils;

public String convertStreamToString(InputStream is) throws IOException { 
    return new String(FileCopyUtils.copyToByteArray(is), StandardCharsets.UTF_8);
}

实用方法org.springframework.util.StreamUtils与其中的实用方法类似FileCopyUtils,但它们在完成时将流保持打开状态。







java list arraylist iterator