问题描述
想象一个多重地图跟踪人员,每个人都有分配的任务列表.
Imagine a multimap tracking persons, each of whom has a list of assigned tasks.
Map< Person , List< Task > > personToTasks =
Map.of(
new Person( "Alice" ) , List.of( new Task( "a1" ), new Task( "a2") ) ,
new Person( "Bob" ) , List.of( new Task( "b1" ) ) ,
new Person( "Carol" ) , List.of( new Task( "c1" ), new Task( "c2"), new Task( "c3") )
)
;
如何使用流获取新地图,将每个Person
映射到Integer
,并在其分配的任务列表中找到项目数?
How can I use streams to get a new map, mapping each Person
to an Integer
with the count of items found in their list of assigned tasks?
如何获得与该硬编码地图等效的结果:
How to get a result equivalent to this hard-coded map:
Map< Person , Integer > personToTaskCount =
Map.of(
new Person( "Alice" ) , 2 ,
new Person( "Bob" ) , 1 ,
new Person( "Carol" ) , 3
)
;
我一直在尝试以下排列:
I have been trying permutations of:
Map < Person, Integer > personToTaskCount =
personToTasks.keySet().stream().collect
(
Collectors.mapping
(
Map.Entry :: getKey ,
???
)
)
;
推荐答案
您在正确的轨道上,这是一个可行的解决方案:
You are on the right track, here's a possible solution:
Map<Person, Integer> personToTaskCount = personToTasks
.entrySet()
.stream()
.collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().size()));
Map#entrySet
方法返回 Set
,一组 Map.Entry
对象. Map.Entry
保存映射中每个条目的键值对.我们可以要求该对象提供键和值.
The Map#entrySet
method returns a Set
of the elements in a map, a set of Map.Entry
objects. A Map.Entry
holds the key-value pairing of each entry in the map. We can ask that object for the key and for the value.
在您的示例情况下,询问每个Map.Entry
的值会得到一个List< Task >
.然后,我们可以查询该列表的大小,包含的元素数量.这个大小数字是我们想要的新地图Map < Person, Integer >
的值.
In your example case, asking for the value of each Map.Entry
gets us a List< Task >
. We can then interrogate that list for its size, the number of elements it contains. This size number is the value we want for your new map, Map < Person, Integer >
.
这是上面代码的扩展版本,以使这些Map.Entry
对象的作用更加明显.
Here is an expanded version of the code above, to make more obvious these Map.Entry
objects in action.
Map < Person, List < Task > > personToTasks =
Map.of(
new Person( "Alice" ) , List.of( new Task( "a1" ) , new Task( "a2" ) ) ,
new Person( "Bob" ) , List.of( new Task( "b1" ) ) ,
new Person( "Carol" ) , List.of( new Task( "c1" ) , new Task( "c2" ) , new Task( "c3" ) )
);
Map < Person, Integer > personToTaskCount =
personToTasks
.entrySet()
.stream()
.collect(
Collectors.toMap(
( Map.Entry < Person, List < Task > > e ) -> { return e.getKey(); } ,
( Map.Entry < Person, List < Task > > e ) -> { return e.getValue().size(); }
)
);
将结果转储到控制台.
System.out.println( "personToTasks = " + personToTasks );
System.out.println( "personToTaskCount = " + personToTaskCount );
运行时.
personToTaskCount = {人物[名称=鲍勃] = 1,人物[名称=爱丽丝] = 2,人物[名称=卡罗尔] = 3}
personToTaskCount = {Person[name=Bob]=1, Person[name=Alice]=2, Person[name=Carol]=3}
这篇关于通过生成映射到其集合值中元素数量的每个键的新映射来报告多图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!