Collectors.toMap 使用相同的键(打印相同的键)
Collectors.toMap with same keys(print same key)
我有这个代码来获取地图:
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
)
);
如何使用重复密钥打印消息 "Duplicate keys"?
how i can print message "Duplicate keys" with duplicate key?
使用您当前的代码,您将收到消息 "Duplicate keys",其中包含 MyObject
的列表,其中至少包含 2 个 MyObject
的实例,它们具有与 [= 的值相等的对象12=],例如 Arrays.asList(new MyObject("foo", "bar"), new MyObject("foo", "bar2"))
.
How to get the corresponding key?
目前无法获取到对应的key,目前merge函数获取到的其实是映射到同一个key的2个value,需要合并,只保留对应key的一个value。
您的问题是一个已知问题,已在 Java 9 中修复,有关详细信息,请参阅 JDK-8040892,相应的修复将使我们能够从合并函数包括要合并的键和值。
另见 Why does Collectors.toMap report value instead of key on Duplicate Key error?
如 中所述,这是一个已知问题,将在 Java 9 中修复——至少对于不接受合并的 toMap
收集器而言功能。
由于合并函数只接收要合并的两个值,签名不能轻易更改,目前还没有针对这些重载方法的修复。不幸的是,没有 toMap
收集器接受没有显式合并功能的 Map
Supplier
,因此除非这会在发布之前改变,否则您的场景将没有修复 LinkedHashMap
应该返回。
所以解决方案是实现自己的收集器。然后,您不必等待 Java 9,也不必冒险失望。
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));
或使用合格的 MyCollector.toMap
,指的是您放置自定义收集器的 class。
我有这个代码来获取地图:
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
)
);
如何使用重复密钥打印消息 "Duplicate keys"?
how i can print message "Duplicate keys" with duplicate key?
使用您当前的代码,您将收到消息 "Duplicate keys",其中包含 MyObject
的列表,其中至少包含 2 个 MyObject
的实例,它们具有与 [= 的值相等的对象12=],例如 Arrays.asList(new MyObject("foo", "bar"), new MyObject("foo", "bar2"))
.
How to get the corresponding key?
目前无法获取到对应的key,目前merge函数获取到的其实是映射到同一个key的2个value,需要合并,只保留对应key的一个value。
您的问题是一个已知问题,已在 Java 9 中修复,有关详细信息,请参阅 JDK-8040892,相应的修复将使我们能够从合并函数包括要合并的键和值。
另见 Why does Collectors.toMap report value instead of key on Duplicate Key error?
如 toMap
收集器而言功能。
由于合并函数只接收要合并的两个值,签名不能轻易更改,目前还没有针对这些重载方法的修复。不幸的是,没有 toMap
收集器接受没有显式合并功能的 Map
Supplier
,因此除非这会在发布之前改变,否则您的场景将没有修复 LinkedHashMap
应该返回。
所以解决方案是实现自己的收集器。然后,您不必等待 Java 9,也不必冒险失望。
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));
或使用合格的 MyCollector.toMap
,指的是您放置自定义收集器的 class。