Я хочу преобразовать Hashmap<String,Long>
в Treemap
, чтобы отсортировать его ключ по string.length (я не могу просто использовать treemap.addAll
, потому что у меня могут быть другие логики c при вставке и я хочу использовать java8)
Код ниже. Но когда ключи с одинаковой длиной существуют в исходном Hashmap, это вызовет функцию слияния, которая выдает исключение (я собираюсь сделать это, потому что в моем случае не будет такой же строки). Интересно, почему функция слияния запускается, поскольку JavaDo c в toMap () говорит: «Если сопоставленные ключи содержат дубликаты (согласно Object # equals (Object)), функция сопоставления значений применяется к каждый равный элемент, и результаты объединяются с использованием предоставленной функции объединения. " Я думаю, что в моем коде «сопоставленные ключи» должны быть записью в hashMap, сопоставленной Entry::getKey
, но не string.length()
в компараторе TreeMap. то есть "ab c"! = "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));
};
}
}