[TOC]
声明
这一系列文章旨在帮助大家理解 Collector
的执行流程,至于实现的是否高效、是否优雅、是否合理等暂且不论。
若对 Collector
的各个流程有疑问请移驾此处:http://blog.csdn.net/hylexus/...
年末了,坑爹的本命年也很快结束了,今天写本命年最后一篇博客:
看着这些名门正派的武功心法(Collectos源码),心底往往会泛起一股淡淡的忧伤,一阶江湖散修的无奈V_V。每每瞄到大派优雅的心法秘诀,内心总会在呐喊:“还有这种操作?”。
不是说看不懂这些大神的实现,只是在没看到人家优雅的实现之前,自己是想不到的V_V。
上次分享的自定义 groupByCollector
实现了分组的功能,但是分组之后的每个分类下都是原来输入的类型。
很多时候,你可能只是需要输入类型的某个属性而已。
比如,分组之后返回的是 Map
,但是你需要的可能仅仅是user的id,也就是你想要的只是这个: Map
,其中只包含了 user.id
。
现在就来试试实现这个功能,当然此处的实现还是很死板的。很多东西都是写死的。不支持像jdk原生分组功能那样灵活的实现和组合。
简单实现
- 此处还是拿上一篇中的例子来说
static class User {
private Integer id;
private String name;
private Integer gender;
private Integer age;
User(Integer id, String name, Integer gender, Integer age) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
}
// getter,setter
}
List users = Lists.newArrayList(
new User(1, "java", 1, 25),
new User(2, "C", 1, 22),
new User(3, "scala", 0, 23),
new User(4, "C++", 0, 11),
new User(5, "Spark", 1, 25),
new User(6, "PHP", 0, 45),
new User(7, "Python", 1, 89),
new User(8, "JavaScript", 0, 110),
new User(9, "C#", 1, 33)
);
- GroupByCollector
/**
* @param 分组之后的key
* @param 中间转换过程的元素类型
* @param 最终的结果类型
* @author hylexus
*/
static class GroupByCollector3
implements Collector>, Map>> {
/**
* 分类器,指定分组之后的key
*/
Function classifier;
/**
* 最后一步的转换函数
*/
Function finisher;
public GroupByCollector3(Function classifier, Function finisher) {
this.classifier = classifier;
this.finisher = finisher;
}
@Override
public Supplier
使用自定义Collector
- 自定义Collector,是获取分组中的userId而非user实例
Map> collect = users.stream()
.collect(new GroupByCollector3<>(User::getGender, User::getId));
collect.forEach((k, v) -> {
System.out.println(k);
System.out.println("\t" + v);
});
- 当然,使用jdk内置的实现起来更优雅
Map> collect = users.stream()
.collect(
Collectors.groupingBy(
User::getGender,
Collectors.mapping(User::getId, Collectors.toList())
)
);
collect.forEach((k, v) -> {
System.out.println(k);
System.out.println("\t" + v);
});
- 输出效果
0
[3, 4, 6, 8]
1
[1, 2, 5, 7, 9]
博客源码
https://github.com/hylexus/bl...