我有这个代码来获取地图:
List<MyObject> myList = myMethod.getList();
myList.stream().collect(
Collectors.toMap(
MyObject::getKey,
MyObject::getValue,
(e1, e2) -> {
System.out.println("Duplicate keys !!!");
return e1;
},
LinkedHashMap::new
)
);
如何使用重复键打印“重复密钥”消息?
答案 0 :(得分:11)
如this answer中所述,这是一个已知的问题,将在Java 9中修复 - 至少对于不接受合并功能的toMap
收集器而言。
由于merge函数只接收要合并的两个值,并且签名不能轻易更改,因此无法解决这些重载方法。遗憾的是,没有toMap
收集器在没有显式合并功能的情况下接受Map
Supplier
,因此除非在发布之前这种情况发生变化,否则您的方案将无法修复{应该返回{1}}。
所以解决方案是实现自己的收集器。然后,您不必等待Java 9,也不必冒险失望。
LinkedHashMap
您可以将此收集器用作
static <T, K, V, M extends Map<K, V>> Collector<T, ?, M> toMap(
Function<T, K> keyExtractor, Function<T, V> valueExtractor, Supplier<M> mapSupplier) {
return Collector.of(mapSupplier,
(m, t) -> putUnique(m, keyExtractor.apply(t), valueExtractor.apply(t)),
(m1,m2)-> { m2.forEach((k, v) -> putUnique(m1, k, v)); return m1; }
);
}
private static <K,V> void putUnique(Map<K,V> map, K key, V v1){
V v2 = map.putIfAbsent(key, v1);
if(v2 != null) throw new IllegalStateException(
String.format("Duplicate key %s (values %s and %s)", key, v1, v2));
}
或使用合格的LinkedHashMap<KeyType, ValueType> map = myList.stream()
.collect(toMap(MyObject::getKey, MyObject::getValue, LinkedHashMap::new));
,指的是放置该自定义收集器的类。
答案 1 :(得分:5)
我如何打印消息&#34;重复键&#34;用重复的键?
使用您当前的代码,您将收到消息&#34; Duplicate keys&#34;使用MyObject
列表,其中包含至少2个MyObject
个getKey()
个实例,这些实例具有与Arrays.asList(new MyObject("foo", "bar"), new MyObject("foo", "bar2"))
相同的对象,例如my_branch
。
如何获取相应的密钥?
到目前为止,无法获得相应的密钥,您当前从合并功能获得的内容实际上是2个值,这些值使用需要合并的相同密钥进行映射,以便只保留相应密钥的一个值。
您的问题已在 Java 9 中修复已知问题,请参阅this answer以获取更多详细信息,相应的修补程序将允许我们从合并功能获取密钥和值合并。