我的天哪~ Stream API 原来如此强大!

98 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情

Hi~ o( ̄▽ ̄)ブ 大家好,这里是杰哥的Java小窝-掘金分站!

1 简介

Steam是Java8中处理集合的关键抽象概念,提供了一种高效且易于使用的数据处理方式,可以执行对指定集合的查找、过滤和映射数据等操作(不会改变源数据集合)。

2 Stream的三个操作步骤及相关函数

2.1 创建Stream

方式1:可通过Collection集合提供的steam()或ParallelStream()来将集合转换为串行流以及并行流

    List<String> list = new ArrayList<>();
    Stream<String> stringStream = list.stream();

方式2:可通过Arrays中静态方法stream获取数组流

    int[] ints = new int[5];
    IntStream integerStream = Arrays.stream(ints);

方法3:通过Stream类中的静态方法of()创建

    Stream<String> stream = Stream.of("aa", "aa", "aa");

方法4:创建无限流(无穷多项的流)

    Stream<Integer> integerStream1 = Stream.iterate(0, (x) -> x + 2);
	//or
    Stream<Double> doubleStream=Stream.generate(Math::random);


2.2 中间操作

多个中间操作可以连接起来形成一个流水线,除非流水线末端触发终止操作,否则中间操作不会执行。(惰性求值)

方法描述备注
Stream filter(Predicate<? super T> predicate);从流中筛选符合条件的元素
Stream limit(long maxSize);截断流,保留前n个元素(有短路效果,即多个中间操作一起作用时,会截断)在流水线操作中有截断效果,即某个流水线有多个中间操作时,对stream遍历至满足limit限制就会停止,可以提高效率。
Stream skip(long n);跳过前n个元素若stream中元素不足n个,则返回空stream
Stream distinct();去重基于hashCode()和equals()去重,对于自定义对象流要重写才能生效
Stream map(Function<? super T, ? extends R> mapper);将流中每个元素都进行转换或提取信息操作,将其映射为一个新的元素
Stream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);将流中的每个值都转换为另一个流,并把所有流都连接起来返回
Stream sorted();按照自然顺序排序
Stream sorted(Comparator<? super T> comparator);按照自定义排序规则进行排序

2.3 终止操作

方法描述备注
boolean allMatch(Predicate<? super T> predicate);检查是否匹配所有元素
boolean anyMatch(Predicate<? super T> predicate);检查是否至少匹配一个元素
boolean noneMatch(Predicate<? super T> predicate);流里是不是没有元素可以匹配指定规则
Optional findFirst();返回符合第一个元素使用Optional是因为结果有可能为空
Optional findAny();返回任意值
Optional max(Comparator<? super T> comparator);返回最大值
Optional min(Comparator<? super T> comparator);返回最小值
long count();返回流中元素总数
1.T reduce(T identity, BinaryOperator accumulator);

2.Optional reduce(BinaryOperator accumulator);

3. U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator combiner);
归约操作: 将流中元素结合起来,得到一个值
<R, A> R collect(Collector<? super T, A, R> collector);收集操作: 将流转换为其他形式(列表、map、set等)Collectors工具类 提供了很多静态方法可以创建常用的Collector收集器(除此之外还包含很多特殊操作函数,例如 分组groupingBy()、连接字符串joining() 等)

demo1:归约reduce

    List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    //样式1,传入二元运算规则,从identity开始累计结合(避免结果为null,不加起始值需要用Optional接收)
    Integer result = list1.stream().reduce(0, Integer::sum);//28

demo2:Collectors 收集List

    List<String> nameList=employeeList.stream()
            .map(Employee::getName)
            .collect(Collectors.toList());

demo3:Collectors List分组

    Map<Integer, List<Employee>> map = employeeList.stream()
            .collect(Collectors.groupingBy(Employee::getAge));

3 并行流与顺序流

3.1 初识

并行流将一个内容分成多个数据块,并使用不同的线程分别处理每个数据块的流。
demo:顺序流与并行流

//        顺序流
        Long sum = LongStream.rangeClosed(0, 1000)//产生0-1000的数字组成LongStream
                .reduce(0, Long::sum);
//        并行流
        Long sum1 = LongStream.rangeClosed(0, 1000)
                .parallel()
                .reduce(0, Long::sum);