这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战
Java 8的Stream允许我们向流水线一样分步骤分节点的处理数据。Java 8 Stream的编程方式又称流式编程,通过将集合数据转化为单项数据流,在数据从源头流向终点的过程中经过一系列的处理后收集到新的容器中(通常是集合)。有点类似于工厂流水线。
journey
title Stream 处理过程示意
section Stream数据源
(1, 2, 3, 10): 7
section 加一
(2, 3, 4, 11): 6
section 过滤大于10的数据
(2, 3, 4): 5
section 收集打包数据
[2, 3, 4]: 4
流中的数据是一个接一个流向下个处理节点,最后经过收集器汇总
根据流中处理数据的方式可以将流分为三种:创建,处理,终止
创建
创建Stream有两种方式:直接创建和基于集合实例创建
直接创建
使用Stream的of、generate、empty、concat、iterate、可以直接创建Stream
of:使用元素直接创建generate:使用Supplier提供的元素创建empty:创建一个空的Streamconcat:连接两个Stream返回一个新的Streamiterate:将函数f迭代应用到初始元素seed产生的无限、有序Stream
基于集合实例创建
Java 8的Collection接口中增加了默认方法stream和parallelStream,这两个方法就是从集合元素创建Stream
此外
java.util.Arrays类中也增加了stream方法,用于根据数组创建Stream
示例:
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连接在一起
示例:
去重过滤
filter: 接受一个Predicate参数,断言为true的元素流向下一个操作,断言为false的元素被过滤distinct: 消除流中的重复元素
示例:
排序
sorted(): 排序sorted(Comparator): 排序,根据Comparator排序
示例:
限制与跳过
limit: 接受一个int参数,保留元素个数skip:接受一个int参数,跳过前n个元素
示例:
终止
终止操作时流中数据处理的最后一步。进行终止操作后流被消费完成,流就不再存在了,此时流不能被再一次消费。终止可以分为:收集、组合、转数组、匹配、查找、统计
收集
collect(Collector):接受一个Collector(收集器)参数,使用收集器收集流元素到集合中collect(Supplier, BiConsumer, BiConsumer):接受三个参数Supplier、BiConsumer、BiConsumer,收集流元素到集合中。第一个参数Supplier创建一个新集合,第二个参数BiConsumer将下一个元素收集到结果集合中,第三个参数BiConsumer用于将两个结果集合合并起来
示例:
组合
reduce:接受一个BinaryOperator参数,使用BinaryOperator来组合所有流中的元素。返回值为Optional类型reduce:接受参数identity、BinaryOperator,功能同上.identity作为其组合的初始值。因此如果流为空identity就是结果
示例:
转数组
toArray():将流转换成适当类型的数组toArray(generator):生成自定义类型的数组
示例:
匹配
allMatch:接受一个Predicate参数,如果流的每个元素都被断言为true,结果返回为 true。在出现第一个断言为false 时,直接返回falseanyMatch:接受一个Predicate参数,如果流的任意一个元素被断言为true,结果返回为 true。在出现第一个断言为 true时直接返回truenoneMatch:接受一个Predicate参数,如果流的每个元素都被断言为false,结果返回为 true。在出现第一个断言为true时,直接返回false
示例:
查找
findFirst:返回流中第一个元素的Optional,如果流为空返回Optional.emptyfindAny:返回流中任意一个元素的Optional,如果流为空返回Optional.empty
示例:
统计
count:返回流中的元素个数。max:接受一个Comparator参数,返回Comparator比较出的最大元素min:接受一个Comparator参数,返回Comparator比较出的最小元素
以下操作只能用于IntStream、LongStream、DoubleStream
average:求取流元素平均值sum:对所有流元素进行求和summaryStatistics:生成可能有用的数据,包含最大值、最小值、平均值等
示例: