Dra-M Dra-M
首页
技术
冥思
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

莫小龙

保持理智,相信未来。
首页
技术
冥思
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Java基础

    • 什么时候使用抽象类
    • 简陋的注解扫描实现
    • Stream流式编程思想及常用API介绍
      • 中间操作、终止操作、惰性求值
      • 顺序流和并行流
      • stream 构建流
      • parallel 并行流
      • 中间操作
        • filter 过滤
        • map 转换
        • flatMap 扁平化
        • distinct 去重
        • limit 截断流
        • skip 跳过
        • sorted 排序
      • 终止操作
        • forEach 遍历
        • findAny findFirst
        • collect 收集器
        • 数据类型转换
        • 分组
        • reduce 归约
        • sum 求和
        • count 计数
        • anyMatch 或运算
        • allMatch 与运算
        • noneMatch 与(非)
  • Spring

  • 微服务

  • Elasticsearch

  • 实用工具

  • Bash

  • DevOps系列

  • 技术
  • Java基础
莫小龙
2020-07-16
目录

Stream流式编程思想及常用API介绍

Stream流像一个流水线,可以理解为将一车对象,放入流水线中,流水线一环一环进行处理。

提示

本文可能需要你先具对备函数式接口和方法引用相关内容的了解。

# 概念

# 中间操作、终止操作、惰性求值

中间操作返回一个流,所以可以连接多个流操作。

终止操作结束流,返回一个void或非流结果。

中间操作的调用相当于对流水线的拼装,只有当终止操作调用时对象才会开始真正流入。

Stream.of("d2", "a2", "b1", "b3", "c")
    .filter(s -> {
        System.out.println("filter: " + s);
        return true;
    });
//由于没有终止操作,filter并没有被执行,所以没有输出。
1
2
3
4
5
6

# 顺序流和并行流

顺序流:对象一个一个流入一个条流水线。

并行流:对象一起流入多条流水线。

# 常用API

# stream 构建流

所有的Collection都可以通过.stream创建一个流。

也可以通过Stream.of方法创建流。

 ArrayList<Integer> integers = new ArrayList<>();
    integers.add(7);
    integers.add(3);
    integers.add(5);
    integers.add(1);
    integers.add(2);
    integers.add(3); 
    Stream<Integer> stream = integers.stream();

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
1
2
3
4
5
6
7
8
9
10

# parallel 并行流

stream.parallel() 将流转为并行流。

提示

他的调用顺序不重要,因为他不像其他的方法对流做拼接,而是改变这个流的一个标记,最后会根据这个标记执行并行还是串行。

# 中间操作

中间操作相当于对流的拼接,由流对象调用,返回的还是流对象。对象会流入环节再流出到下一个,调用顺序决定拼接顺序。

# filter 过滤

接收一个对象流入,接受一个布尔值返回,扔掉false的对象,放行为true的对象。

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    integerStream.filter(i -> i > 3).forEach(System.out::print);
    //45
1
2
3

# map 转换

接收一个对象流入,流出一个对象。

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    integerStream.map(i -> "数字" + i).forEach(System.out::print);
    // 数字1数字2数字3数字4数字5
1
2
3

# flatMap 扁平化

将一个对象拆分成流,再把拆分出的流的流出流汇总到一起流出。

    ArrayList<List<Integer>> arrayList = new ArrayList<>();
    ArrayList<Integer> integers1 = new ArrayList<>();
    ArrayList<Integer> integers2 = new ArrayList<>();
    integers1.add(1);
    integers1.add(2);
    integers1.add(3);
    integers2.add(4);
    integers2.add(5);
    integers2.add(6);
    arrayList.add(integers1);
    arrayList.add(integers2);

    arrayList.stream()
        .flatMap(a -> a.stream().skip(1))
        .forEach(System.out::print);
    //2356
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# distinct 去重

    Stream<Integer> integerStream = Stream.of(1, 2, 2, 2, 5);
    integerStream.distinct().forEach(System.out::print);
    // 125
1
2
3

# limit 截断流

接收一个int值,当流入对象够数后停止流入

    Stream<Integer> integerStream = Stream.of(1, 2, 2, 2, 5);
    integerStream.limit(2).forEach(System.out::print);
    // 12
1
2
3

# skip 跳过

接受一个int值,抛弃前几个流入的对象

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    integerStream.skip(3).forEach(System.out::print);
    // 45
1
2
3

# sorted 排序

接收两个对象,排序。

    Stream<Integer> integerStream = Stream.of(4, 2, 1, 3);
    integerStream.sorted((i1, i2) -> i2 - i1).forEach(System.out::print);
    //4321
1
2
3

顺序问题

当[1,2]经过流abcd时,顺序是a1-b1-c1-d1 a2-b2-c2-d2。 但因为sorted是把多个对象变得有序,所以需要等对象全部流入后处理,完成后再一个个流出。 所以中间有排序s,即abscd,会变成a1-b1 a2-b2 s1,2 c1-d1 c2-d2。

# 终止操作

终止操作返回void或非流对象,他的后边不再拼接其他操作,只有终止操作被拼接时,流才会开始流入对象。

# forEach 遍历

返回值void,消费每一个对象。

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    integerStream.forEach(System.out::print);
    // 12345
1
2
3

# findAny findFirst

当一个对象流入时,终止流并返回对象。 findAny在并行时不能保证初始顺序,findFirst可以。

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    Optional<Integer> any = integerStream.findAny();
    System.out.println(any.get());
    // 1
1
2
3
4

# collect 收集器

# 数据类型转换

    Stream<Integer> integerStream = Stream.of(4, 2, 1, 3);
    Set<Integer> set = integerStream.collect(Collectors.toSet());
1
2

# 分组

接受一个传入参数,传出结果的方法,根据结果分组。

根据布尔结果分组。

    Stream<Integer> integerStream = Stream.of(4, 2, 1, 3, 3, 4, 2);
    Map<Boolean, List<Integer>> collect = integerStream.collect(Collectors.groupingBy(a -> a > 3));
    System.out.println(collect);
    //{false=[2, 1, 3], true=[4]}
1
2
3
4

根据字符串分组。

public class DemoApplication {
  public static void main(String[] args) {
    Stream<Integer> integerStream = Stream.of(4, 2, 1, 3, 3, 4, 2);
    Map<String, List<Integer>> collect =
        integerStream.collect(Collectors.groupingBy(DemoApplication::get));
    System.out.println(collect);
    // {大=[4, 4], 中=[3, 3], 小=[2, 1, 2]}
  }
  static String get(Integer i) {
    if (i > 3) {
      return "大";
    }
    if (i == 3) {
      return "中";
    }
    return "小";
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# reduce 归约

接收一个初始值,两个传入值,处理后返回结果。

    Stream<Integer> integerStream = Stream.of(1,2,3);
    Integer integer = integerStream.reduce(0,(a, b) -> a + b);
    System.out.println(integer);
    //6 
1
2
3
4

# sum 求和

相当于 reduce(0, Integer::sum)

# count 计数

返回流到终点的对象数。

# anyMatch 或运算

# allMatch 与运算

# noneMatch 与(非)


#函数式编程#Stream流
上次更新: 3/5/2021
简陋的注解扫描实现
彻底透析SpringBoot jar可执行原理

← 简陋的注解扫描实现 彻底透析SpringBoot jar可执行原理→

最近更新
01
易混淆哲学用语释义
04-13
02
前言:搭建一套自有的围绕K8S的DevOps工具
04-11
03
部署K8S -- kubeasz
04-11
更多文章>
Theme by Vdoing | Copyright © 2019-2022 Dra-M | 冀ICP备2021002204号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式