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

莫小龙

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

    • JUC

      • 为什么不用Executors去创建线程池
    • Spring

    • Gradle

    • 面向对象

    • Stream流式编程思想及常用API介绍
      • 中间操作、终止操作、惰性求值
      • 顺序流和并行流
      • stream 构建流
      • parallel 并行流
      • 中间操作
        • filter 过滤
        • map 转换
        • flatMap 扁平化
        • distinct 去重
        • limit 截断流
        • skip 跳过
        • sorted 排序
      • 终止操作
        • forEach 遍历
        • findAny findFirst
        • collect 收集器
        • 数据类型转换
        • 分组
        • reduce 归约
        • sum 求和
        • count 计数
        • anyMatch 或运算
        • allMatch 与运算
        • noneMatch 与(非)
    • JAVA快速导出Excel
  • Golang

  • 编程思想

  • 微服务

  • 中间件

  • Python

  • 运维

  • 技术
  • 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流#编程思想
上次更新: 10/23/2024
什么时候使用抽象类
JAVA快速导出Excel

← 什么时候使用抽象类 JAVA快速导出Excel→

最近更新
01
mosquito配置ws协议
10-23
02
Pip包的离线下载和安装
10-23
03
stable diffusion 相关收藏
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Dra-M
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式