使用流根据List <Bar>的大小对Map <Foo,List <Bar >>进行分组

Ale*_*ard 3 java java-8 java-stream collectors

我正在尝试转换此格式的数据:

Map<Foo, List<Bar>> mapFooToBars;         //start Map
Map<Integer, List<Foo>> mapListSizeToFoos //destination Map
Run Code Online (Sandbox Code Playgroud)

我想基于List<Bar>每个条目的大小创建一个分组,这样在我的输出映射中,我将有一个列表,其中所有Foos一起有0个条,所有Foos一起有1个条,依此类推.

我试图这样做:

Map<Foo, List<Bar>> fooBarMap = whatever();
fooBarMap.entrySet().stream()
    .collect(Collectors.groupingBy(entry -> entry.getValue().size()));
//expected Map<Integer,Entry<Foo, List<Bar>> which
//could be transformed into Map<Integer,Foo> pretty easily
Run Code Online (Sandbox Code Playgroud)

我显然不清楚groupingBy是如何工作的,因为这给了我一个"getValue()未定义类型Object"错误.沿着这条线的某个地方,我正在丢失关于entrySet的类型信息,我猜?这让我想知道这不是最好的解决方法.任何帮助赞赏!

Mis*_*sha 6

你走在正确的轨道上.你应该使用groupingBybut with mapping(Map.Entry::getKey, toList())作为第二个参数.这会将密钥收集到列表中,这些列表将是生成的映射的值.

fooBarMap.entrySet().stream()
    .collect(groupingBy(
        e -> e.getValue().size(),
        mapping(Map.Entry::getKey, toList())
    ));
Run Code Online (Sandbox Code Playgroud)

假设静态导入各种收集器