记Java8新特性的学习(一)---Stream流处理及基本概念

最近项目组内引入的新鲜血液较多,最让人清晰的感受到一些新技术点的迭出,其中印象最深的就是Java8的流式处理,以及经常听却没常写的Lambda表达式,实在忍不住这种对知识的渴望,遂写几篇随笔记录一下Java8新特性的学习。

那么我还是从大纲开始说吧,从网上找的知识点,让人奇怪的是Java8出来这么多年了,百度最新的帖子依旧是2014年的介绍文,所以我这边也就先从菜鸟教程以及网上找的一部分部分的介绍开始切入了。后续发现更多优质资源时在补充此块内容。

首先大致说下此次的内容特性说明:

1。Lambda表达式

2。函数式接口

3。方法引用于构造器引用

4。StreamApi

5。接口中默认的方法与静态方法

6。新时间日期Api

7。其他新特性

那么由于我这边项目组目前接触的产品是偏大数据可视化的,我会优先从StreamApi流 的基础使用及Lambda表达式开始,其次是新日期APi,最后才是其他几个模块的内容学习

好的 那我们正式开始进入下一步的学习:

一:StreamApi流式处理

1.内容了解:

Java8中有两大最为重要的改变。第一个是Lambda 表达式;另外一个则是Stream API(java.util.stream.*)。
Stream 是Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL 执行的数据库查询。也可以使用Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

2.什么是Stream:

流是指的数据渠道,所谓的数据渠道就是用于数据源(集合,数组等)所生成的元素序列,

这里用Java8的一句介绍可清晰理解  “”集合讲的是数据,而流讲的是计算“”

三个主要点:

1.Stream不会存储元素,主要是作为渠道来计算

2.Stream不会改变源对象,相反,他们会返回一个持有结果的新Stream

3.Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行

三个基本步骤:

1.创建Stream:

通过一个数据源(如集合数组)获取一个流

1.1 Java8中的Collection接口被扩展了,提供了两个获取流的方法:

default Stream<E> stream();返回一个顺序流

default Stream<E> parallelStream() 返回一个并形流

1.2 Java8中的Arrays的静态方法Stream()可以获取数组流

static <T> Stream<T>  stram(T[]  array); 返回一个流

1.3 重载形式能够处理对应基本类型的数组:

public static IntStream stream (int  [] array);

public static LongStream stream(long [] array);

public static DoublieStream stream(double [] array)

1.4 静态方法Stream.of()显示创建流

public static<T> Stream<T> of(T ...Value);

1.5 无线流

Stream.iterate()  迭代流 

Stream.generate()  生成流

2.中间操作:

构造一个中间操作链,在终止操作时对数据源的数据行处理

多个中间操作可以连接成一个流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,称为惰性求值

常用中间操作:

2.1. filter(Predicate P)

接受Lambda,从流中排出掉某些元素。  

2.2 distinct() 

筛选,通过流生成的元素hashcode() 和equal() 去除重复的元素。    用途:合并list中的元素,统计次数啥的

2.3 limit(long maxSize)

截断流,使其元素不超过给定数量

2.4 skip(long n)

跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流,与limit(n)互补 

2.5 map(Function f)

接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素 很简便的一个集合函数遍历功能

2.6 mapToDouble(ToDoubleFunction f)    mapToInt(ToIntFunction f)    mapToLong(ToLongFunction f) 

接受一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的DoubleString/IntStream/LongStream 很简便的一个集合函数遍历功能

2.7 flatMap(Function f)

接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

2.8 sorted()  

产生一个新流,并按自然顺序排序

2.9 sorted(Comparator comp)

产生一个新流,并按比较器顺序排序

3.终止操作:

一个终止操作,执行中间操作链,并产生结果,终止操作会从流的流水线生成结果,其结果可以是任何不是流的值,例如List  Interge 甚至是void 

常用方法: 

3.1 allMatch(predicate p)

检查是否匹配所有元素

3.2 anyMatch(Predicate  p) 

检查是否匹配至少一个元素

3.3 noneMatch(Predicate p)

检查是否没有匹配到所有元素

3.4 findFirst()

返回第一个元素

3.5 findAny()

返回当前流中的任意元素

3.6 count()

返回流中元素总数

3.7 max(Comparator c)

返回流中最大值

3.8 min (Conparator c)

返回流中最小值

3.9 forEach(Consumer c)

内部迭代,使用Collection接口需要用户去做迭代,称为外部迭代,相反,StreamAPi使用内部迭代,它完成了迭代的功能

4.0 reduce(T iden,BinartOprator b) 

可以将流中元素反复结合起来,得到一个值,返回T

4.1 reduce(Binaryoperator b)

可以将流中元素反复结合起来,得到一个值,返回Optional<T>

备注:

大家常听的Map-Reduce,就是来源于流这,map和reduce的连接通常被称为map-reduce模式,因Geogle用它来进行网络搜索而出名

4.2 collect(Collector c)

将流转换成其他形式,接受一个collector接口的实现,用于给Stream中元素做汇总的方法。

Collector 接口方法的实现决定了如何对流执行收集操作,但是Collectors实用类提供了许多静态方法,可以方便的创建常见的收集器实例,具体方法与实例如下:

 三:并行流与串行流

1.基本概念

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。,java8中将并行进行了优化,我们可以很容易的对数据进行并行操作,StreanApi的Parallel()与sqquential()能实现流在并行流与顺序流(串行流)之间进行切换。

2.Fork/Join框架(适用于 任务之间无关系耦合   任务可单独运行)

Fork/Join框架就是在必要情况下,可以将一个大任务,进行拆分(fork)成若干个小任务(拆到不可再拆),再将一个个小任务运算结果进行Join汇总

 3.Fork/Join框架与传统线程池的区别

Fork/Join采用工作窃取模式(Work-stealing),当执行新的任务时,它可以将其拆分成更小的任务执行,并将小任务加到线程队列中,然后再从一个随机线程的队列中偷一个并把它放在自己的队列中。

相对于传统的线程实现,fork/join框架的优势体现在对其中包含任务的处理方式上,在一般线程池中,如果一个线程正在执行的任务由于某些原因无法继续运行,那么该线程会处于等待状态,而在forK/join框架实现中,如果某个子问题的由于等待另外一个子问题的完成而无法继续运行,那么处理该孩子的线程会主动找到其他尚未运行的子问题来执行,这种方式减少了线程的等待时间,提高了性能。

猜你喜欢

转载自www.cnblogs.com/hnusthuyanhua/p/12617728.html