本篇将入门Java函数式编程中的收集器。
收集器相关操作
之前提到过及早求值方法和惰性求值法,而它们的区别通常就和收集器的存在有关,简单的说,收集器可以从流生成复杂值。
在开始收集器各操作之前,先构造一个用于测试的实例,在该实例中,最重要的就是创建了一个HashMap对象,该对象放入了5组键值对,后续很多用收集器操作的数据都来自于此:
|
|
转换成其它集合
首先HashMap对象不能直接流化,nameAndArt.stream()
报错。要想使nameAndArt中的成员对应单个流元素,可以采用entrySet():
|
|
运行结果:
|
|
在具体的实操中,要注意区分Stream.of
和stream()
的区别,看下面的代码:
|
|
这段代码打印出的结果是:
|
|
结果上它们完全相同,但是第二个打印语句中可以调用HashMap的方法:
|
|
第一句不能完成x.entrySet()的调用,但是第一句可以通过filter方法进行条件过滤,所以每个HashMap对象仍对应一个流元素。
转换成List的方法就是将toSet改成toList,如果要指定转换的具体类型,可以使用下面这种方式:
|
|
需要转换成什么类型就将toCollection中的参数进行指定即可。
Lambda表达式可以赋给Function接口,然后再作为参数进行传递。比如:
|
|
接下来就以这个函数为比较逻辑,求出一个minBy:
|
|
最后输出为:
|
|
数据分类
这里的分类,包含分块和分组。所谓分块,就是将流分解成两个集合。通过收集器返回的是一个Map,键为true和false,直接看代码就明白了:
|
|
输出:
|
|
所谓分组,比前面提到的分块更自由和灵活,生成的Map对象的键不局限于true和false,下面用代码说明:
|
|
输出:
|
|
仍然是返回一个Map对象,但这里被要求以x.getValue()为键进行分组。
Collectors的功能很强大,还提供joining方法,处理字符串流,也举一个简单的例子说明:
|
|
输出:
|
|
"*", "%", "%"
分别代表分隔符,前缀和后缀。
组合收集器
之前分组的例子中,以值为键并以键值对为值创建Map对象打印输出,能否在原有代码基础上,将输出的格式改变为以值为键以键作为组成列表的元素的形式呢?
采用组合收集器的方式,代码:
|
|
groupingBy函数内嵌入mapping函数,mapping内嵌入toList函数,这种组合的方式相较于传统的循环语句,逻辑更加清晰。
输出为:
|
|
小结
本篇主要专注于收集器,罗列了它的一些主要的操作,也了解了点这方面的编程细节。