这真的是一个关于小细节的问题,但我觉得这里有些地方错了。如果您使用Collectors.toMap-method添加重复的键,它会抛出一个异常,并显示消息"duplicate key“。为什么报告的是值,而不是键?或者两者兼而有之?这真的很误导,不是吗?
下面是一个演示行为的小测试:
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TestToMap {
public static void main(String[] args) {
List<Something> list = Arrays.asList(
new Something("key1", "value1"),
new Something("key2", "value2"),
new Something("key3", "value3a"),
new Something("key3", "value3b"));
Map<String, String> map = list.stream().collect(Collectors.toMap(o -> o.key, o -> o.value));
System.out.println(map);
}
private static class Something {
final String key, value;
Something(final String key, final String value){
this.key = key;
this.value = value;
}
}
}
发布于 2016-10-14 17:35:05
这被报告为一个错误,请参阅JDK-8040892,它在Java9中得到了修复。
String.format("Duplicate key %s (attempted merging values %s and %s)", k, u, v)
其中k
是重复的键,u
和v
是映射到同一键的两个冲突值。
发布于 2016-10-14 18:45:44
正如其他答案已经指出的,这是一个将在Java9中修复的错误。出现错误的原因是,toMap
依赖具有签名的Map.merge
V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)
此方法将插入key
-value
映射,如果之前没有key
的映射,否则将计算remappingFunction
以计算新值。因此,如果不允许重复的键,那么直接提供一个remappingFunction
,它将无条件地抛出一个异常,这样就完成了。但是…如果您查看函数签名,您会注意到此函数只接收要合并的两个值,而不是键。
当throwingMerger
为Java8实现时,人们忽略了第一个参数不是关键,但更糟糕的是,它不是直接修复的。
如果您尝试使用overloaded toMap
collector提供另一种合并,您会注意到这一点。键值在这一点上根本不在作用域中。为了避免重复,Java9开发人员必须更改整个toMap
实现,以便能够提供报告受影响的关键…的异常消息
发布于 2016-10-14 17:37:15
这是Jdk 8中的一个已知错误。抛出的消息应该至少显示两个存在键冲突的值,或者理想情况下应该显示发生冲突的键。附件中是相同的link
https://stackoverflow.com/questions/40039649
复制相似问题