我正在尝试将可用List
的{{1}}转换为Currency
,要基于货币数字代码进行查找,我想获取String代码。这是代码。
但是上面的这段代码抛出了错误,我对Java 8还是很陌生,所以我大吃一惊:
Map
但是上面的这段代码抛出了错误,我对Java 8还是很陌生,所以我大吃一惊
Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.IllegalStateException: Duplicate key YUM
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1556)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
它应该以代码为键将所有货币加载到地图中。
答案 0 :(得分:4)
Collectors.toMap()
不接受重复的密钥。
由于您拥有Currency::getNumericCode
的密钥,因此toMap()
在遇到重复密钥时会引发此异常。
Caused by: java.lang.IllegalStateException: Duplicate key YUM
请注意,此处的错误消息具有误导性。键是Integer
,而YUM
不是。 YUM
看起来像一个Currency
实例,就是这样。
实际上,YUM
指的是Currency
处理的具有重复键的值(toMap()
)之一,而不是键值本身。这是Java bug fixed in Java 9。
要解决您的问题,请使用Collectors.groupingBy()
收集到Map<Integer, List<Currency>>
,在这种情况下,您可以通过键获得多个值,或者将重复的键合并为toMap()
,例如保留最后一个条目:
private static final Map<Integer, Currency> NUMERIC_MAP =
ISO_CURRENCY.stream()
.collect(Collectors.toMap(Currency::getNumericCode, Function.identity(), (v1, v2)-> v2);
要回答您的评论,您可以通过以下方式找到罪魁祸首代码(重复项):
Map<Integer, List<Currency>> dupMap =
ISO_CURRENCY.stream()
.collect(Collectors.groupingBy(Currency::getNumericCode)
.entrySet()
.filter(e -> e.getValue().size() > 1)
.collect(Collectors.toMap(Entry::getKey,Entry::getValue));
System.out.println(dupMap);