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

Use streams to group Map<Foo,List<Bar>> based on size of the List<Bar>

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

Map<Foo, List<Bar>> mapFooToBars;         //start Map
Map<Integer, List<Foo>> mapListSizeToFoos //destination Map

我想根据每个条目的 List<Bar> 的大小创建一个分组,这样在我的输出映射中,我会有一个包含 0 个条的所有 Foos 的列表,所有有 1 个小节的 Foos,依此类推。

我正在尝试这样做:

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

我显然不清楚 groupingBy 的确切工作原理,因为这给我一个 "getValue() is undefined for the type Object" 错误。我猜在某个地方丢失了关于 entrySet 的类型信息?这让我想知道这是否不是解决此问题的最佳方法。感谢任何帮助!

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

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

以上假定各种收集器的静态导入