Почему для аргумента Java mapFactory метода toMap в классе Collectors необходимо указать типы?
Следующий код не компилируется с моим JDK14:
Map<Integer, String> map = Arrays.asList("this", "is", "just", "an", "example").stream()
.collect(Collectors.toMap(w -> w.length(),
w -> w,
(existing, replacement) -> replacement,
() -> new TreeMap<>(Comparator.reverseOrder())));
в то время как, если я укажу типы для конструктора TreeMap, он отлично работает:
Map<Integer, String> map4 = Arrays.asList("this", "is", "just", "an", "example").stream()
.collect(Collectors.toMap(w -> w.length(),
w -> w,
(existing, replacement) -> replacement,
() -> new TreeMap<Integer, String>(Comparator.reverseOrder())));
Я что-то упустил или есть ошибка в системе стирания типов в JDK14?
1 ответ
Кажется, есть проблема с выводом типа для Comparator
в случае цепных вызовов.
Это может сработать, если вы заранее создадите поставщика карты (кстати, не только в JDK14):
Supplier<Map<Integer, String>> supplier = () -> new TreeMap<>(Comparator.reverseOrder());
Map<Integer, String> mapWithSupplier = Arrays.asList("this", "is", "just", "an", "example").stream()
.collect(Collectors.toMap(w -> w.length(),
w -> w,
(existing, replacement) -> replacement,
supplier));
Если вы использовали Collections.reverseOrder()
, вы бы вообще не столкнулись с этой проблемой:
Map<Integer, String> mapCollectionReversed = Arrays.asList("this", "is", "just", "an", "example").stream()
.collect(Collectors.toMap(w -> w.length(),
w -> w,
(existing, replacement) -> replacement,
() -> new TreeMap<>(Collections.reverseOrder())));
или хотя бы заранее создал компаратор:
Comparator<Integer> comparator = Comparator.reverseOrder();
Map<Integer, String> mapWithComparator = Arrays.asList("this", "is", "just", "an", "example").stream()
.collect(Collectors.toMap(w -> w.length(),
w -> w,
(existing, replacement) -> replacement,
() -> new TreeMap<>(comparator)));
И без reverseOrder
карта может быть успешно создана с TreeMap::new
:
Map<Integer, String> map = Arrays.asList("this", "is", "just", "an", "example").stream()
.collect(Collectors.toMap(w -> w.length(),
w -> w,
(existing, replacement) -> replacement,
TreeMap::new));