【发布时间】:2020-02-20 07:03:35
【问题描述】:
我想将Hashmap<String,Long> 转换为Treemap,以便按string.length 对其键进行排序(我不能简单地使用treemap.addAll,因为插入时我可能有其他逻辑并且我想使用java8)
代码如下。但是当初始 Hashmap 中存在相同长度的键时,它会触发合并函数,该函数会抛出异常(我打算这样做,因为在我的情况下不会有相同的字符串)。我想知道为什么会触发合并函数,因为 toMap() 的 JavaDoc 说“如果 映射键 包含重复项(根据 Object#equals(Object)),则值映射函数应用于每个相等元素,并使用提供的合并功能合并结果。”我认为在我的代码中,“映射键”应该是由 Entry::getKey 映射的 hashMap 中的条目,而不是 TreeMap 比较器中的 string.length()。即“abc”!=“def”。所以它不应该触发合并。但??什么鬼?
public class TestToMap {
public static Map<String, Long> map1 = new HashMap<String, Long>() {
{
put("abc", 123L);
put("def", 456L);
}
};
public static void main(String[] args) {
Map<String, Long> priceThresholdMap = map1.entrySet().stream()
.collect(Collectors.toMap(Entry::getKey,
Entry::getValue,
throwingMerger(),
() -> new TreeMap<String, Long>(
(a, b) -> {
return a.length() - b.length();
}))); // this will trigger merge function, why?
//() -> new TreeMap<String, Long>(Comparator.comparingInt(String::length).thenComparing(String::compareTo)))); // but this won't trigger merge function
}
private static <T> BinaryOperator<T> throwingMerger() {
return (u, v) -> {
throw new IllegalStateException(String.format("priceThresholdMap has duplicate v1 %s,v2 %s", u, v));
};
}
}
【问题讨论】:
标签: java java-8 merge collectors