【问题标题】:Optimal way to transfer values from a Map<K, V<List>> to a Map<otherKey, otherValue<List>>将值从 Map<K, V<List>> 传输到 Map<otherKey, otherValue<List>> 的最佳方式
【发布时间】:2022-01-05 17:26:57
【问题描述】:

以下是我要处理的内容: Map&lt;Faction, List&lt;Resource&gt;&gt;

  • Faction 是玩家阵营的枚举字符串值(例如“rr”代表红队,“bb”代表蓝队)
  • Resources 是资源的字符串枚举值,例如“Wool”、“Lumber”

所以列表现在看起来像这样:

("rr", "wool")
("rr", "wool")
("rr", "lumber")
("bb", "wool")

所以我的目标是拥有一个Map&lt;Resource, Integer&gt;

  • 其中 Resource 是枚举中资源的字符串名称
  • 整数表示资源卡的数量

目标包含值示例:("Wool", 4), ("Grain", 3), ("Lumber", 2)


所以我正在尝试这样做(在伪代码中):

  • 提取属于Faction“rr”的所有资源,并将它们放入映射&lt;Resources, Integer&gt;,其中每种资源类型应表示一次,Integer表示Resource卡片数量的总和 --> 对另外 3 个玩家重复此步骤Faction

我玩过流和 foreach 循环,但还没有生成有价值的代码,因为我还在构思阶段挣扎。

【问题讨论】:

  • 您是在寻找解决方案,还是您有解决方案但想要更好的解决方案?如果您有解决方案,可以发布吗?

标签: java intellij-idea lambda collections java-stream


【解决方案1】:

Map&lt;Faction, List&lt;Resource&gt;&gt; 中的实际输入数据看起来像:

{rr=[wool, wool, lumber], bb=[lumber, wool, grain]}

假设为ResourceFaction 使用了适当的枚举,则可以使用flatMap 为输入映射中的值检索资源与其数量的映射:

Map<Faction, List<Resource>> input; // some input data

Map<Resource, Integer> result = input
    .values() // Collection<List<Resource>>
    .stream() // Stream<List<Resource>>
    .flatMap(List::stream) // Stream<Resource>
    .collect(Collectors.groupingBy(
        resource -> resource,
        LinkedHashMap::new, // optional map supplier to keep insertion order
        Collectors.summingInt(resource -> 1)
    ));

Collectors.toMap 可以申请:

...
    .collect(Collectors.toMap(
        resource -> resource,
        resource -> 1,
        Integer::sum,      // merge function to summarize amounts
        LinkedHashMap::new // optional map supplier to keep insertion order
    ));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-23
    • 2013-12-20
    • 2019-10-10
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    相关资源
    最近更新 更多