【问题标题】:How do I use Java 8 groupingBy to collect into a list of a different type?如何使用 Java 8 groupingBy 收集到不同类型的列表中?
【发布时间】:2019-12-11 00:43:47
【问题描述】:

我正在尝试获取A -> A 类型的地图,并将其分组到A to List<A> 的地图中。 (也颠倒了键值关系,但我认为这不一定相关)。

这就是我现在拥有的:

private static Map<Thing, List<Thing>> consolidateMap(Map<Thing, Thing> releasedToDraft) {

    // Map each draft Thing back to the list of released Things (embedded in entries)
    Map<Thing, List<Map.Entry<Thing, Thing>>> draftToEntry = releasedToDraft.entrySet().stream()
            .collect(groupingBy(
                    Map.Entry::getValue,
                    toList()
            ));

    // Get us back to the map we want (Thing to list of Things)
    return draftToEntry.entrySet().stream()
            .collect(toMap(
                    Map.Entry::getKey,
                    ThingReleaseUtil::entriesToThings
            ));
}

private static List<Thing> entriesToThings(Map.Entry<Thing, List<Map.Entry<Thing, Thing>>> entry) {
    return entry.getValue().stream()
            .map(Map.Entry::getKey)
            .collect(toList());
}

我想在单个语句中执行此操作,并且我觉得必须可以将 Map&lt;Thing, List&lt;Map.Entry&lt;Thing, Thing&gt;&gt;&gt; 转换为 Map&lt;Thing, List&lt;Thing&gt;&gt; 作为 groupingBy 操作的一部分。

我试过使用reducing(),自定义收集器,我能找到的一切;但是我因为缺乏复杂的例子而受阻,而且我能找到的几个类似的例子有List.of(),这在 Java 8 中不存在(Collections.singletonList() 似乎不是一个好的替代品)。

有人可以帮我解决可能很明显的问题吗?

【问题讨论】:

  • 您可以使用Arrays.asList() 代替List.of()。此外,List.of() 创建了一个不可变列表,因此如果要修改它,您需要将其包装在您最喜欢的 List 实现的 constructor 中。
  • @Scary Wombat 你能告诉我你编辑了什么,为什么?没有编辑评论,差异似乎没有显示任何变化。
  • 刚刚格式化了您的代码,但看起来您同时进行了一些重新格式化。

标签: java java-8 reducing groupingby


【解决方案1】:

必须在行

private static Map<Thing, List<Thing>> consolidateMap(Map<Thing, Thing> releasedToDraft) {
        return releasedToDraft.entrySet().stream()
                .collect(groupingBy(
                        Map.Entry::getValue,
                        mapping(Map.Entry::getKey, toList())
                ));
    }

【讨论】:

  • 我知道我在哪里犯了错误。键/值被颠倒了。所以它有效。试试这个。 Map&lt;Integer, Integer&gt; map = Map.of(1, 1, 3, 1, 5, 1, 6, 2, 8, 2, 10, 2); 将其用作您的测试地图。然后它将有 1 个映射到奇数值列表和 2 映射到偶数值列表。所以我原来的说法是错误的。你的回答很好。
  • 不错的答案。只需稍作改动就可以了,因为 static importCollectors. API 不一致。将所有静态更改 Collectors.mapping 导入到 mapping 或其他方式。旁白:如果现有答案(如您所链接的)已经解决了问题,请将其标记为重复。
  • @Naman 我使用 Eclipse,坦率地说,它对静态类的支持并不是那么好。它们不像其他导入那样“粘”。
  • @WJS 好吧,相反,我并没有真正使用 Eclipse。但如果它不粘,那么所有这些都应该使用Collectors. 限定,如.collect(Collectors.groupingBy(Map.Entry::getValue, Collectors.mapping(Map.Entry::getKey, Collectors.toList())))。主要动机是要求确保一致性,无论首选哪个。
  • @WJS “粘性”是什么意思?我对 Eclipse 和import static 没有任何问题...
猜你喜欢
  • 2017-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-22
相关资源
最近更新 更多