在Java8中,何时在Collectors.toMap中触发合并功能?

问题描述 投票:0回答:1

我想将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));
        };
    }
}
java java-8 merge collectors
1个回答
1
投票
© www.soinside.com 2019 - 2024. All rights reserved.