为了账号安全,请及时绑定邮箱和手机立即绑定

如何将迭代器转换为流?

如何将迭代器转换为流?

天涯尽头无女友 2019-11-22 12:54:58
我正在寻找一种Iterator将a 转换为Stream或更具体地以将“迭代器”作为流“查看”的简洁方法。出于性能原因,我想避免在新列表中复制迭代器:Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();Collection<String> copyList = new ArrayList<String>();sourceIterator.forEachRemaining(copyList::add);Stream<String> targetStream = copyList.stream();根据评论中的一些建议,我也尝试使用Stream.generate:public static void main(String[] args) throws Exception {    Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();    Stream<String> targetStream = Stream.generate(sourceIterator::next);    targetStream.forEach(System.out::println);}但是,我得到了NoSuchElementException(因为没有调用hasNext)Exception in thread "main" java.util.NoSuchElementException    at java.util.AbstractList$Itr.next(AbstractList.java:364)    at Main$$Lambda$1/1175962212.get(Unknown Source)    at java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1351)    at java.util.Spliterator.forEachRemaining(Spliterator.java:326)    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)    at Main.main(Main.java:20)我已经看过StreamSupport和Collections,但我没有发现任何东西。
查看完整描述

3 回答

?
慕哥9229398

TA贡献1877条经验 获得超6个赞

一种方法是从迭代器创建一个拆分器,并将其用作流的基础:


Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();

Stream<String> targetStream = StreamSupport.stream(

          Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),

          false);

一种可能更易读的替代方法是使用Iterable-使用lambda从Iterator创建Iterable非常容易,因为Iterable是一个功能性接口:


Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();


Iterable<String> iterable = () -> sourceIterator;

Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);


查看完整回答
反对 回复 2019-11-22
?
潇湘沐

TA贡献1816条经验 获得超6个赞

很棒的建议!这是我可重复使用的方法:


public class StreamUtils {


    public static <T> Stream<T> asStream(Iterator<T> sourceIterator) {

        return asStream(sourceIterator, false);

    }


    public static <T> Stream<T> asStream(Iterator<T> sourceIterator, boolean parallel) {

        Iterable<T> iterable = () -> sourceIterator;

        return StreamSupport.stream(iterable.spliterator(), parallel);

    }

}

和用法(确保静态导入asStream):


List<String> aPrefixedStrings = asStream(sourceIterator)

                .filter(t -> t.startsWith("A"))

                .collect(toList());


查看完整回答
反对 回复 2019-11-22
?
慕斯王

TA贡献1864条经验 获得超2个赞

在Java 9中,仅使用流就可以做到这一点,但是需要注意。以下朴素的示例将无法显示迭代器的最后一个元素。


Stream.generate(iterator::next)

    .takeWhile(i -> iterator.hasNext()) 

    .forEach(System.out::println);

但是,这确实可以正常工作:


Stream.generate(() -> null)

    .takeWhile(x -> iterator.hasNext())

    .map(n -> iterator.next())

    .forEach(System.out::println);


查看完整回答
反对 回复 2019-11-22
  • 3 回答
  • 0 关注
  • 548 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信