Java8Stream

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

Java 8的Stream允许我们向流水线一样分步骤分节点的处理数据。Java 8 Stream的编程方式又称流式编程,通过将集合数据转化为单项数据流,在数据从源头流向终点的过程中经过一系列的处理后收集到新的容器中(通常是集合)。有点类似于工厂流水线。

Stream数据源

Stream数据源

(1, 2, 3, 10)

(1, 2, 3, 10)

加一

加一

(2, 3, 4, 11)

(2, 3, 4, 11)

过滤大于10的数据

过滤大于10的数据

(2, 3, 4)

(2, 3, 4)

收集打包数据

收集打包数据

[2, 3, 4]

[2, 3, 4]Stream 处理过程示意

流中的数据是一个接一个流向下个处理节点,最后经过收集器汇总

根据流中处理数据的方式可以将流分为三种:创建处理终止

创建

创建Stream有两种方式:直接创建基于集合实例创建

直接创建

使用Streamofgenerateemptyconcatiterate、可以直接创建Stream

  • of:使用元素直接创建
  • generate:使用Supplier提供的元素创建
  • empty:创建一个空的Stream
  • concat:连接两个Stream返回一个新的Stream
  • iterate:将函数f迭代应用到初始元素seed产生的无限、有序Stream

image.png

基于集合实例创建

Java 8的Collection接口中增加了默认方法streamparallelStream,这两个方法就是从集合元素创建Stream
image.png
此外java.util.Arrays类中也增加了stream方法,用于根据数组创建Stream
image.png
示例:

ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1);
arrayList.add(2);
Stream<Integer> stream = arrayList.stream();

Set<String> hashSet = new HashSet<>();
hashSet.add("A");
hashSet.add("B");
Stream<String> stream1 = hashSet.stream();

Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("A", 1);
hashMap.put("B", 2);
// Map没有继承Collection接口,需要先转为Set
Stream<Map.Entry<String, Integer>> stream2 = hashMap.entrySet().stream();

String[] strings = {"a", "b"};
Stream<String> stream3 = Arrays.stream(strings);
复制代码

处理

处理就像是流水线上一个个的加干步骤,主要有转换过滤排序等操作

调试查看

  • peek: 接受一个Consumer参数, 不会改变原数据

转换

  • map: 接受一个Function参数,流中的数据会被替换成Function的返回值
  • flatMap: 接受一个Function参数,Function的返回值是Stream类型,flatMap会把Function的返回值是Stream连接在一起

示例:
image.png

去重过滤

  • filter: 接受一个Predicate参数,断言为true的元素流向下一个操作,断言为false的元素被过滤
  • distinct: 消除流中的重复元素

示例:
image.png

排序

  • sorted(): 排序
  • sorted(Comparator): 排序,根据Comparator排序

示例:
image.png

限制与跳过

  • limit: 接受一个int参数,保留元素个数
  • skip:接受一个int参数,跳过前n个元素

示例:
image.png

终止

终止操作时流中数据处理的最后一步。进行终止操作后流被消费完成,流就不再存在了,此时流不能被再一次消费。终止可以分为:收集组合转数组匹配查找统计

收集

  • collect(Collector):接受一个Collector(收集器)参数,使用收集器收集流元素到集合中
  • collect(Supplier, BiConsumer, BiConsumer):接受三个参数SupplierBiConsumerBiConsumer,收集流元素到集合中。第一个参数Supplier创建一个新集合,第二个参数BiConsumer将下一个元素收集到结果集合中,第三个参数BiConsumer用于将两个结果集合合并起来

示例:
image.png

组合

  • reduce:接受一个BinaryOperator参数,使用BinaryOperator来组合所有流中的元素。返回值为Optional类型
  • reduce:接受参数identityBinaryOperator,功能同上. identity作为其组合的初始值。因此如果流为空identity就是结果

示例:
image.png

转数组

  • toArray():将流转换成适当类型的数组
  • toArray(generator):生成自定义类型的数组

示例:
image.png

匹配

  • allMatch:接受一个Predicate参数,如果流的每个元素都被断言为true,结果返回为 true。在出现第一个断言为false 时,直接返回false
  • anyMatch:接受一个Predicate参数,如果流的任意一个元素被断言为true,结果返回为 true。在出现第一个断言为 true时直接返回true
  • noneMatch:接受一个Predicate参数,如果流的每个元素都被断言为false,结果返回为 true。在出现第一个断言为true时,直接返回false

示例:
image.png

查找

  • findFirst:返回流中第一个元素的Optional,如果流为空返回Optional.empty
  • findAny:返回流中任意一个元素的Optional,如果流为空返回 Optional.empty

示例:
image.png

统计

  • count:返回流中的元素个数。
  • max:接受一个Comparator参数,返回Comparator比较出的最大元素
  • min:接受一个Comparator参数,返回Comparator比较出的最小元素

以下操作只能用于IntStreamLongStreamDoubleStream

  • average :求取流元素平均值
  • sum:对所有流元素进行求和
  • summaryStatistics:生成可能有用的数据,包含最大值、最小值、平均值等

示例:
image.png