Java8 函数式功能速查

本文最后更新于:2020年12月30日 凌晨

场景

有时候使用 lambda 参数的时候忘记应该接口的名字,所以便在此写一下 Java8
function 包下原生的相关接口,方便快速查找。

lambda 接口

class 参数 返回值 Stream 示例 应用场景
Function <T> <R> map/flatMap 映射
Consumer <T> void forEach/peek 迭代
Predicate <T> boolean filter/anyMatch 过滤
Supplier <R> generate 生成
BiFunction <U,T> <T> reduce 归纳
UnaryOperator <T> <T> iterate 映射相同类型
BinaryOperator <T,T> <T> reduce 归纳相同类型
Comparator <T,T> <U> sort 比较

Stream 流

Stream 流为我们提供了一种简单的操作集合的方式,每个操作都具有原子性。

function 参数 返回值 功能
filter Predicate<T> Stream<T> 过滤
map Function<T,T> Stream<T> 映射
flatMap Function<T,Stream<T>> Stream<T> 压平映射
distinct Stream<T> 去重
sorted Stream<T> 排序, 要求 T 实现 Closeable
sorted Comparator<T> Stream<T> 排序
peek Consumer<T> Stream<T> 迭代,但有返回值
limit long Stream<T> 限制数量
skip long Stream<T> 从开头丢弃指定数量的元素
forEach Consumer<T> void 迭代
forEachOrdered Consumer<T> void 保证顺序的迭代
toArray Object[] 转换为数组
toArray IntFunction<T[]> T[] 转换为指定类型的数组
reduce BinaryOperator<T> Optional<T> 归纳为一个元素
collect Collector<T,A,R> R 将结果归集
min Comparator<T> Optional<T> 最小值
max Comparator<T> Optional<T> 最大值
count long 长度
anyMatch Predicate<T> boolean 是否存在匹配的元素
allMatch Predicate<T> boolean 是否所有元素都匹配
noneMatch Predicate<T> boolean 是否所有元素都不匹配
findFirst Optional<T> 查找第一个元素
findAny Optional<T> 查找任意一个元素
empty Stream<T> 获取一个空的流
of T... Stream<T> 将多个元素构造为流
iterate T,UnaryOperator<T> Stream<T> 构造无限有序流
generate Supplier Stream<T> 构造无限无序流
concat Stream<T>,Stream<T> Stream<T> 连接两个流
parallel Stream<T> 将流转换为并行模式(多线程)

Collectors

Collectors 是一个 Java8 增加的一个工具类,用于简单的构造 Collector 接口的实现,主要用于 Stream.collect() 中的参数。Stream.collect() 用于将流转换为其他的数据结构,包括但不限于 Collection, Map, String, Long 等等,并以此衍生出了许多有用的操作:分组,转换为 Map,归约(reduce 的另一种使用方式),连接(归约的特化形式)

function 功能 示例
toList 转换为 List
toSet 转换为 Set
toMap 转换为 Map
toCollection 转换为 Collection 的子类
joining 所有元素连接为 String, 可以指定分隔符/开头/结尾
mapping 在转换之前对每个元素进行映射,常用于分组
collectingAndThen 在转为之前对结果进行一些操作,例如构造不可变集合
counting 计算元素总数
minBy 最小值
maxBy 最大值
summingInt 计算总和(结果为 Integer
summingLong 计算总和(结果为 Long
summingDouble 计算总和(结果为 Double
averagingInt 计算平均值(结果为 Integer
averagingLong 计算平均值(结果为 Long
averagingDouble 计算平均值(结果为 Double
reducing 归纳, 与 Stream.reduce() 功能相同
groupingBy 分组, Collectors 独有
groupingByConcurrent 并发分组
partitioningBy 特化分组, 分成 truefalse
toMap 转换为 Map
toConcurrentMap 转换为并发 Map
summarizingInt 汇总信息并尽可能返回 Integer。注: summarizing* 的方法汇总的信息都是 数量/求和/平均值/最小值/最大值
summarizingLong 汇总信息并尽可能返回 Long
summarizingDouble 汇总信息并尽可能返回 Double

一些示例

常见 Stream 操作

1
2
3
4
5
6
7
8
9
10
final List<String> collect = Stream.of("1", "12", "", "123", "2", "12", "321", "")
//过滤
.filter(s -> !s.isEmpty())
//提取出组成字符串的字符
.flatMap(s -> Arrays.stream(s.split("")))
//去重
.distinct()
//转换为集合
.collect(Collectors.toList());
System.out.println(collect); //结果是 [1, 2, 3]

常见 Collectors 操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
final Map<Integer, List<List<String>>> collect = Stream.of("1", "12", "", "123", "2", "13", "321", "")
.collect(
//分组
Collectors.groupingBy(
//分组条件
String::length,
//分组之前对每个元素进行映射
Collectors.mapping(
//映射函数
s -> Arrays.asList(s.split("")),
//最后将 Stream 转换为 List
Collectors.toList()
)
)
);
System.out.println(collect); //结果是 {0=[[], []], 1=[[1], [2]], 2=[[1, 2], [1, 3]], 3=[[1, 2, 3], [3, 2, 1]]}

最后,Java8 有很多有趣的功能,或许我们所使用的不过是其中一个很小的子集,然而了解的越多越是觉得 Java8 的改进很多呢

注:本文并非 API 列表,并未包含全部的功能,所以如果找不到所需要的函数可以查看 JDK8 Oracle Documentation


Java8 函数式功能速查
https://blog.rxliuli.com/p/a15c161497d14819971f4854862475f0/
作者
rxliuli
发布于
2020年4月18日
许可协议