重复的键(尝试合并值x和x)

18

我有一个简单的类:

public class Rule {
    int id;
    long cableType;
}

我想将一个包含此类对象的列表转换为Map<Integer, Long>,所以我写了以下代码:
Map<Integer, Long> map = ruleList.stream().collect(Collectors.toMap(Rule::getId, Rule::getCableType));

列表中存在重复项,如(1, 10), (1,40),当我运行此代码时,会出现以下异常:

Exception in thread "main" java.lang.IllegalStateException: Duplicate key 21 (attempted merging values 31 and 30)

我该如何修复这个问题?


在简单的 Map 中,不能将两个不同的值映射到相同的键。 - Koenigsberg
我认为这需要一个预处理。但是你想如何处理重复的值?将cableType求和,保留第一个,保留最后一个,... - Anthony Raymond
3个回答

38
为了避免这个错误,您需要取其中一个重复的条目作为示例,为此您需要:
.collect(Collectors.toMap(Rule::getId, Rule::getCableType, (r1, r2) -> r1));

3
不错,我不知道收集器可以使用lambda来解决重复键。 - Anthony Raymond
2
API文档请点击此处 - EndlessLoop

1
值得注意的是,在使用.collect之前,您可能需要考虑使用.sorted(Comparator.comparing(rule -> rule.cableType))或类似方法,这样您就可以有意识地选择在重复键情况下保留哪些值。
@Youcef的答案确实消除了异常,但是对于重复键选择的值取决于列表当前的顺序。

0

我知道问题已经解决了,但我刚刚发现了这个很酷的 .distinct() 运算符。

所以我建议使用:

Map<Integer, Long> map = ruleList.stream().distinct().collect(Collectors.toMap(Rule::getId, Rule::getCableType));

如何区分不同的规则对象?它们不都是针对像 OP 提供的数据 (1, 10), (1,40) 的唯一对象吗?所以我认为这不会起作用。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接