1

想象一个多地图跟踪人员,每个人都有一个分配任务列表。

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") ) 
    )
;

如何使用流来获取新地图,将每个地图映射PersonInteger在其分配任务列表中找到的项目数?

如何获得与此硬编码地图等效的结果:

Map< Person , Integer >  personToTaskCount = 
    Map.of(
        new Person( "Alice" ) , 2 , 
        new Person( "Bob" )   , 1 , 
        new Person( "Carol" ) , 3 
    )
;

我一直在尝试以下排列:

Map < Person, Integer > personToTaskCount = 
        personToTasks.keySet().stream().collect
        (
            Collectors.mapping
            (
                Map.Entry :: getKey ,
                ???
            )
        )
;
4

1 回答 1

2

您走在正确的轨道上,这是一个可能的解决方案:

Map<Person, Integer> personToTaskCount = personToTasks
    .entrySet()
    .stream()
    .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue().size()));

Map#entrySet方法返回Set地图中的一个元素,一组Map.Entry对象。AMap.Entry保存映射中每个条目的键值对。我们可以向该对象询问键和值。

在您的示例中,询问 each 的值Map.Entry会给我们一个List< Task >. 然后我们可以询问该列表的大小,它包含的元素数量。这个尺寸数字是我们想要的新地图的值,Map < Person, Integer >

这是上面代码的扩展版本,以使这些Map.Entry对象的作用更加明显。

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 );

跑的时候。

personToTasks = {Person[name=Alice]=[Task[title=a1], Task[title=a2]], Person[name=Carol]=[Task[title=c1], Task[title=c2], Task[标题=c3]],人[name=Bob]=[任务[title=b1]]}

personToTaskCount = {Person[name=Bob]=1,Person[name=Alice]=2,Person[name=Carol]=3}

于 2021-01-12T01:16:47.337 回答