Почему для аргумента 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));
Другие вопросы по тегам