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 构建流
parallel 并行流
中间操作
filter 过滤
map 转换
flatMap 扁平化
distinct 去重
limit 截断流
skip 跳过
sorted 排序
终止操作
forEach 遍历
findAny findFirst
collect 收集器
数据类型转换
分组
reduce 归约
sum 求和
count 计数
anyMatch 或运算
allMatch 与运算
noneMatch 与(非)

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-2025 Dra-M
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式