Stream流整理

一、概述

JDK 1.8新增的Stream,配合Lambda,给操作集合(Collection)提供了极大的便利。

那么什么是StreamStream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。

Stream可以由数组或集合创建,对流的操作分为两种:

  • 中间操作,每次返回一个新的流,可以有多个。

  • 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。

另外,Stream有几个特性:

  1. stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。

  1. stream不会改变数据源,通常情况下会产生一个新的集合或一个值。

  1. stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。

二、常用方法

2.1 创建

Stream有三种创建方式

  1. 通过java.util.Collection.stream()方法用集合创建流

  1. 使用java.util.Arrays.stream(T[] array)方法用数组创建流

  1. 使用Stream的静态方法:of()iterate()generate()

2.1.1 通过集合创建流


List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> parallelStream = list.parallelStream();
  • 串行流:适合存在线程安全问题、阻塞任务、重量级任务,以及需要使用同一事务的逻辑。

  • 并行流:适合没有线程安全问题、较单纯的数据处理任务。

2.1.2 使用数组创建流


int[] array = {1,3,5,6,8};
IntStreamstream= Arrays.stream(array);

2.1.3 使用静态方法


Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);

Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

输出结果:


0 3 6 9
0.6796156909271994
0.1914314208854283
0.8116932592396652

streamparallelStream的简单区分:stream是顺序流,由主线程按顺序对流执行操作,而parallelStream是并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如:筛选集合中的奇数,两者的处理不同之处:如果流中的数据量足够大,并行流可以加快处速度。

除了直接创建并行流,还可以通过parallel()把顺序流转换成并行流:


Optional<Integer> findFirst = list.stream().parallel().filter(x -> x > 6).findFirst();

关于更多的Parallel Stream,请参考:Java Parallel StreamJava Stream之Parallel Streams编程指南

2.2 中间操作

2.2.1 筛选与切片

  1. filter(Predicate):筛选流中某些元素

  1. limit(long val):截断流,取流中前val个元素

  1. skip(n):跳过n元素,配合limit(n)可实现分页

  1. distinct():通过流所生成元素的equalshashCode去重

2.2.2 映射

  1. map(Function f):接收流中元素,并且将其映射成为新元素,例如:从student对象中取name属性

  1. flatMap(Function f):将所有流中的元素并到一起连接成一个流

2.2.3 消费

  1. peek(Consumer c):获取流中元素,操作流中元素,与foreach不同的是不会截断流,可继续操作。

使用场景:当遍历完数组后还有后续操作时或list数组转stream时,不适合在用Iterable的foreach循环,这个时候peek就派上用场了。

2.2.4 排序

  1. sorted()/sorted(Comparator):产生一个新流,按照自然顺序/比较器规则排序


  ArrayList<Integer> number = new ArrayList<>();
        number.add(12);
        number.add(121);
        number.add(23);
        number.add(45);
        number.add(67);
        number.add(67);
        number.add(77);
        number.add(98);
        number.add(99);
        number.add(67);
        Stream<Integer> distinct = number.stream().filter(x -> x > 50)//121,67,67,77,98,99,67
                .skip(2)//67,77,98,99,67
                .sorted()//67,67,77,98,99
                .distinct()//67,77,98,99
                .limit(3);//67,77,98
        distinct.forEach(System.out::println);

2.3 终止操作

2.3.1 匹配/聚合操作

匹配


  1. allMatch(Predicate):当流中每个元素都符合该断言时才返回true,否则返回false

  1. noneMatch(Predicate):当流中每个元素都不符合该断言时才返回true,否则返回false

  1. anyMatch(Predicate):只要流中有一个元素满足该断言则返回true,否则返回false

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值