重庆建设造价工程信息网站,网络营销专业学校排名,wordpress指定文章使用不用模板,什么网站可以在线做高中题目转载自   跟我学 Java 8 新特性之 Stream 流#xff08;七#xff09;流与迭代器#xff0c;流系列大结局 
恭喜你们#xff0c;马上就要学完Java8 Stream流的一整系列了#xff0c;其实我相信Stream流对很多使用Java的同学来说#xff0c;都是一个知识盲点#xff0c;因…转载自   跟我学 Java 8 新特性之 Stream 流七流与迭代器流系列大结局 
恭喜你们马上就要学完Java8 Stream流的一整系列了其实我相信Stream流对很多使用Java的同学来说都是一个知识盲点因为这个原因我才这么细致地讲解Stream流的各个知识点通过这一整个系列我相信只要认真看了的同学都已掌握的差不多了就差实战了。 
其实我在工作过程中Stream流对我的帮助真的挺大的所以我想和大家分享一下于是这系列的文章就出来了。 
在本系列文章发布的时候有很多同学反映Stream流的调试和forEach()的调试都不是特别友好那本篇给出一个折中的调试方法虽然不能完美解决调试的问题但是基本上已经能解决绝大部分的调试问题了没错就是迭代器了当然迭代器除了能辅助调试以外他最重要的还是遍历功能。 
这篇文章除了介绍传统的迭代器外还会介绍Java8中新增的Spliterator因为在并行流的场合Spliterator相当的好用。 
先简单介绍一下传统的迭代器 
迭代器是实现了Iterator接口的对象并且Iterator接口允许遍历获取或者移除元素。 
public interface IteratorE {IteratorT iterator();E next();default void remove() {throw new UnsupportedOperationException(remove);}default void forEachRemaining(Consumer? super E action) {Objects.requireNonNull(action);while (hasNext())action.accept(next());}} 
使用Iterator的一般步骤 
(1)通过iterator()方法获取指向集合或流开头的迭代器。 
(2)建立一个hasNext()方法调用循环只要hasNext()返回true,就继续迭代。 
(3)在循环中通过调用next()方法获取每个元素。 
private static void learnIterator() {ListString lists  Arrays.asList(A, B, C, D);IteratorString iterator  lists.stream().iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}
} 
但是如果我们不修改集合的情况下使用forEach()其实更加便利的其实两种方式本质上面是一样的在你编译之后forEach()会转换成迭代器的方式进行操作了。有了迭代器相信调试就得方便起来了即使不能直接调试也可以通过迭代器反推之前可能发生了什么。 
值得注意的一点是Java8给基本类型的流提供了额外的迭代器PrimitiveIterator.OfInt,PrimitiveIterator.OfDouble,PrimitiveIterator.OfLong,PrimitiveIterator,但这些接口都是来扩展自Iterator接口的所以使用上面也是相同的。 
Spliterator 
Spliterator是Java8新增的一种迭代器这种迭代器由Spliterator接口定义Spliterator也有普通的遍历元素功能这一点与刚才说的迭代器类似的但是但是Spliterator方法和使用迭代器的方法是不同的。 
另外它提供的功能要比Iterator多。最终要的一点Spliterator支持并行迭代。 
public interface SpliteratorT {boolean tryAdvance(Consumer? super T action);int characteristics();long estimateSize();SpliteratorT trySplit();default void forEachRemaining(Consumer? super T action) {do { } while (tryAdvance(action));}
} 
将Spliterator用于基本迭代任务是非常简单的只需要调用tryAdvance()方法直至其返回false.如果要为序列中的每个元素应用相同的动作那么forEachRemaining()提供了一种更加高效的替代方法。 
对于这两个方法在每次迭代中将发生的动作都由Consumer对象定义的操作来决定Consumer也是一个函数式接口估计大家已经知道怎么分析了这里就不带大家分析了他的动作是指定了在迭代中下一个元素上执行的操作。下面来一个简单的例子 
private static void learnIterator() {ListString lists  Arrays.asList(A, B, C, D);SpliteratorString spliterator  lists.stream().spliterator();while (spliterator.tryAdvance(System.out::println));
} 
使用forEachRemaining()方法改进这个例子 
private static void learnIterator() {ListString lists  Arrays.asList(A, B, C, D);lists.stream().spliterator().forEachRemaining(System.out::println);
} 
注意使用这个方法时不需要提供一个循环来一次处理一个元素而是将各个元素作为一个整体来对待这是Spliterator的又一个优势。 
Spliterator的另一个值得注意的方法是trySplit()它将被迭代的元素划分成了两部分返回其中一部分的新Spliterator,另一部分则通过原来的Spliterator访问。下面再给一个简单的例子 
private static void learnIterator() {ListString lists  Arrays.asList(A, B, C, D);SpliteratorString spliterator  lists.stream().spliterator();SpliteratorString stringSpliterator  spliterator.trySplit();if (stringSpliterator ! null) stringSpliterator.forEachRemaining(System.out::println);System.out.println(------------------);spliterator.forEachRemaining(System.out::println);
} 
打印的结果 
A B ------------------ C D 
这里只是给大家提供了这种方式而已例子本身没有什么含义但是当你对大数据集执行并行处理时拆分可能是极有帮助的了。但更多情况下要对流执行并行操作时使用其他某个Stream方法更好而不必手动处理Spliterator的这些细节Spliterator最适合的场景是给定的所有方法都不能满足你的要求时才考虑。 
最后来一个总结 
到这里Java8 Stream流的知识基本上已经介绍完了缩减操作并行流映射还有收集是Stream流的核心内容但是要想掌握好这些内容第二篇的基本知识你是跑不掉的因此我的建议还是老老实实从第一篇开始认真看看完这7篇文章你基本已经非常系统地掌握Java8的Stream流知识了。 
大家也不要忘记Collectors类里面提供给我们的方法基本上能处理各种各样的收集元素问题了如果你从第一篇文章开始看一直看到这里了那你以后尽量多使用Stream流来处理集合吧只是学会这些知识是没有用的要多在你们的项目中运用他们这样才能更加好地理解如果大家在使有的过程中遇到什么样的问题欢迎来这里面留言我看到了一定第一时间和大家一起探索解决的方法。 
如果大家对这一系列文章感兴趣的话也可以关注一下本公众号后面作者会出一系列数据结构方面的文章当然是Java的一整个系列数据结构啦。 
如果你觉得Stream流这系列文章你们能看得比较懂的话那我相信数据结构系列的文章你们也会有同样的感觉的最后谢谢大家祝你们技术越来越强生活越来越愉快最重要的还是马上找到女朋友哈哈哈哈。