Java 8 的 groupingBy 能否产生空的 Map 分组
我们在 Java 8 之前用 for-loop 对 List 进行分组的时候,可能会要求产生空的分组。例如对 List<Person> 按性能进行分组,即使给定的 List<Person> 中全是 male, 我们也想得到 Map 包含两个 Key
类 Person 代码
进行分组
得到结果是
结果中的组只能是列表元素中存在的 gender 属性值
怎么才能向 groupingBy 传递要为列表 ["male", "female"] 中的所有元素创建一个分组呢? 即便是某个分组是空的,找不到匹配的元素。
慢着,当我读到 Partitioning 部分时,眼前又亮了一下. Partitioning 是给 Stream 分两组,非此即比,如代码
输出为
partitioningBy 一启动便预置了两个 key, true 和 false, 对于 grouping 的话恐怕是必须要创建自己的 groupingBy 方法,它能够接受一个列表来预定义 Map 中所有的 key. 永久链接 https://yanbin.blog/java-8-groupingby-howto-generate-empty-map/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
{male=[person1, person2], female=[]}而不只是
{male=[person1, person2]}这两种表示略有区别,第一种方式暗示着有另一种可能性。看看 for-loop 如何对 List<Person> 进行分组。
类 Person 代码
1class Person {
2
3 public final String name;
4 public final String gender;
5
6 public Person(String name, String gender) {
7 this.name = name;
8 this.gender = gender;
9 }
10
11 @Override
12 public String toString() {
13 return name;
14 }
15}进行分组
1List<Person> list = Arrays.asList(new Person("Tom", "male"), new Person("Jerry", "male"));
2Map<String, List<Person>> grouped = new HashMap<>();
3List<Person> maleGroup = new ArrayList<>();
4List<Person> femaleGroup = new ArrayList<>();
5for(Person person: list) {
6 if(person.gender.equals("male")) {
7 maleGroup.add(person);
8 } else {
9 femaleGroup.add(person);
10 }
11}
12grouped.put("male", maleGroup);
13grouped.put("female", femaleGroup);
14System.out.println(grouped);得到结果是
{female=[], male=[Tom, Jerry]}如果我们换成 Java 8 的 groupingBy 的写法
1List<Person> list = Arrays.asList(new Person("Tom", "male"), new Person("Jerry", "male"));
2Map<String, List<Person>> grouped = list.stream().collect(groupingBy(person -> person.gender));
3System.out.println(grouped);结果中的组只能是列表元素中存在的 gender 属性值
{male=[Tom, Jerry]}当然上面从 list 到 groupingBy 时根本不存在 female 的信息,那么能否告知 groupingBy 对不存在 gender 生成空列表呢? 好像无法做到
1Map<String, List<Person>> grouped = list.stream()
2 .collect(groupingBy(person -> "male".equals(person.gender) ? "male" : "female"));怎么才能向 groupingBy 传递要为列表 ["male", "female"] 中的所有元素创建一个分组呢? 即便是某个分组是空的,找不到匹配的元素。
慢着,当我读到 Partitioning 部分时,眼前又亮了一下. Partitioning 是给 Stream 分两组,非此即比,如代码
1List<Person> list = Arrays.asList(new Person("Tom", "male"), new Person("Jerry", "male"));
2Map<Boolean, List<Person>> grouped = list.stream()
3 .collect(partitioningBy(t -> "male".equals(t.name)));
4System.out.println(grouped);输出为
{false=[Tom, Jerry], true=[]}注意到了吗,true 是一个空的列表,说明 partitioning 有能力生成空的列表,进一步猜想 groupingBy 如能稍加打造是否也能做到像 {female=[], make=[Tom, Jerry]} 这样的输出呢?
partitioningBy 一启动便预置了两个 key, true 和 false, 对于 grouping 的话恐怕是必须要创建自己的 groupingBy 方法,它能够接受一个列表来预定义 Map 中所有的 key. 永久链接 https://yanbin.blog/java-8-groupingby-howto-generate-empty-map/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。