1. Java Stream 方法概述

Java 8 API 添加的一个新抽象叫做流 Stream,可以用一种声明的方式处理数据。Stream 使用一种类似 SQL 语句的方式,将要处理的元素集合看做一种流,流在管道中传输,并可以在管道节点上进行处理,如筛选、排序、聚合等。

1.1 什么是 Stream

Stream 是一个来自数据源的元素队列,并支持聚合操作。

  • Stream 不存储元素,而是按需计算。
  • 流的来源:集合、数组、IO、产生器。
  • 聚合操作:类似 SQL 语句的操作,如 filter, map, reduce, find, match, sorted。

Stream 和 Collection 操作区别:

  • 流水线:Stream 中间操作会返回流对象,这样可以构造流水线结构。
  • 内部迭代:Collection 的迭代都是 Iterator 或 for-each,是外部迭代。Stream 提供了内部迭代,通过访问者模式 visitor 实现。

2. 基本方法

2.1 生成流 stream

生成流有两种方式:

  • stream():普通流。
  • parallelStream():并行流。
List<Integer> listA = Arrays.asList(3, 2, 3);
listA.stream();

2.2 迭代 forEach

forEach 提供内部迭代:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

2.3 映射 map

map 映射每个元素到对应结果:

List<Integer> listA = Arrays.asList(3, 2, 3);
List<Integer> listB = listA.stream().map(i -> i * i).distinct().collect(Collectors.toList());

2.4 过滤 filter

filter 设置条件过滤元素:

List<String> listA = Arrays.asList("abc", "def", "");
int intB = listA.stream().filter(s -> s.isEmpty()).count();
list = list.stream()
            .filter(person -> person.getAge() == 20)
            .collect(toList());

2.5 指定数量 limit

limit 获取指定数量的流:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

2.6 排序 sorted

sorted 需要 Comparable 接口已经定义好。不然需要实现 Comparator 接口。

sorted 对流进行排序:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

2.7 去重 distinct

distinct 根据 equals() 判断是否相等。因此,equals() 需要先定义好。

2.8 匹配 anyMatch, allMatch, noneMatch

anyMatch, allMatch, noneMatch 用于判断是否有一个元素 / 全部元素 / 没有元素匹配条件。

boolean b = list.stream().anyMatch(person -> person.getAge() == 20);

2.9 查找 findAny, findFirst

findAny, findFirst 分别用于查找任意一个和第一个元素。

2.10 组合 reduce

reduce 用于组合元素,如进行求和、求积、求最大值。

reduce 第一个值可以是初始值。也可以不设初始值,直接进行运算,但这样就需要考虑没有初始值,需要返回 Optional 对象。

// 有初始值
int sumA = listA.stream().map(Person::getAge).reduce(0, (a, b) -> a + b);
// 没有初始值
Optional<Integer> sumB = listA.stream().map(Person::getAge).reduce(Integer::sum);

2.11 元素个数 count

count 返回流中元素个数。

2.12 收集 collect

collect 返回集合元素。常用的有 collect(toSet) 和 collect(toList)。

3. 常用表述

3.1 找最大值

int max = Arrays.stream(arrayA).max().getAsInt();

3.2 求和

int sum = Arrays.stream(arrayA).sum();

参考内容

  1. 菜鸟教程:Java 8 Stream

  2. 知乎:java8 stream 常用方法