我想将Hashmap<String,Long>
转换为Treemap
,以便按string.length对其键进行排序(我不能简单地使用treemap.addAll
,因为插入时我可能还有其他逻辑,我想使用java8 )
下面的代码。但是,当初始Hashmap中存在相同长度的键时,它将触发合并函数并引发Exception(我打算这样做是因为在我的情况下不会有相同的字符串)。我不知道为什么会触发合并函数,因为toMap()的JavaDoc说“如果mapped keys包含重复项(根据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));
};
}
}