Stream流常见方法浅析
Stream流常见方法浅析
flatMap
flatMap方法用于将流中的每个元素转换成其他类型元素的流,比如,当前有一个订单(Order)列表,每个订单又包含多个商品(itemList),如果要得到所有订单的所有商品汇总,就可以使用该方法,如下:
| 1 | Stream<Item> allItemStream = orderList.stream().flatMap(order -> order.itemList.stream()); | 
distinct
distinct方法用于对流中的元素去重,判断元素是否重复使用的是equals方法
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 0, 1, 2, 2, 3); | 
sorted
sorted有一个无参和一个有参的方法,用于对流中的元素进行排序。无参方法要求流中的元素必须实现Comparable接口,不然会报java.lang.ClassCastException异常
| 1 | Stream<Integer> unorderedStream = Stream.of(5, 6, 32, 7, 27, 4); | 
有参方法sorted(Comparator<? super T> comparator)不需要元素实现Comparable接口,通过指定的元素比较器对流内的元素进行排序
| 1 | Stream<String> unorderedStream = Stream.of("1234", "123", "12", "12345", "123456", "1"); | 
peek
peek方法可以不调整元素顺序和数量的情况下消费每一个元素,然后产生新的流,主要是用于对流执行的中间过程做debug的时候使用,因为Stream使用的时候一般都是链式调用的,所以可能会执行多次流操作,如果想看每个元素在多次流操作中间的流转情况,就可以使用这个方法实现
| 1 | Stream.of("one", "two", "three", "four") | 
skip(long n)
skip方法用于跳过前n个元素,如果流中的元素数量不足n,则返回一个空的流
| 1 | Stream<String> stringStream = Stream.of("-2", "-1", "0", "1", "2", "3"); | 
forEachOrdered
forEachOrdered方法可以保证顺序遍历,比如这个流是从外部传进来的,然后在这之前调用过parallel方法开启了多线程执行,就可以使用这个方法保证单线程顺序遍历
| 1 | Stream<String> stringStream = Stream.of("-2", "-1", "0", "1", "2", "3"); | 
reduce
reduce有三个重载方法,作用是对流内元素做累进操作
第一个reduce(BinaryOperator<T> accumulator)
accumulator 为累进操作的具体计算
单线程等价如下代码
| 1 | boolean foundAny = false; | 
第二个reduce(T identity, BinaryOperator<T> accumulator)
identity 为累进操作的初始值accumulator 同上
单线程等价如下代码
| 1 | T result = identity; | 
第三个reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)
identity和accumulator同上combiner用于多线程执行的情况下合并最终结果
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); | 
collect
collect有两个重载方法,主要作用是把流中的元素作为集合转换成其他Collection的子类,其内部实现类似于前面的累进操作
第一个collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner)
supplier 需要返回开始执行时的默认结果accumulator 用于累进计算用combiner 用于多线程合并结果
单线程执行等价于如下代码
| 1 | R result = supplier.get(); | 
第二个collect(Collector<? super T, A, R> collector)
Collector其实是对上面的方法参数的一个封装,内部执行逻辑是一样的,只不过JDK提供了一些默认的Collector实现,对于
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); | 
anyMatch
anyMatch方法用于匹配校验流内元素是否有符合指定条件的元素
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); | 
allMatch
allMatch方法用于匹配校验流内元素是否所有元素都符合指定条件
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); | 
noneMatch
noneMatch方法用于匹配校验流内元素是否都不符合指定条件
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); | 
findFirst
findFirst方法用于获取第一个元素,如果流是空的,则返回Optional.empty
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); | 
findAny
findAny方法用于获取流中的任意一个元素,如果流是空的,则返回Optional.empty,因为可能会使用多线程,所以不保证每次返回的是同一个元素
| 1 | Stream<Integer> numStream = Stream.of(-2, -1, 0, 1, 2, 3); |