В этом ответе Я попытался создать статический метод утилиты, чтобы сделать List
в Map
:
public static <K, T> Map<K, T> toMapBy(List<T> list,
Function<? super T, ? extends K> mapper) {
return list.stream().collect(Collectors.toMap(mapper, Function.identity()));
}
Это прекрасно работает. Однако я обнаружил, что метод не может использоваться во всех тех же контекстах, что и выражение list.stream().collect(...)
. Метод не такой гибкий.
List<Student> students = Arrays.asList();
Map<Long, Student> studentsById1 = students.stream()
.collect(Collectors.toMap(Student::getId, Function.identity()));
Map<Long, Student> studentsById2 = toMapBy(students, Student::getId);
Map<Long, Person> peopleById1 = students.stream()
.collect(Collectors.toMap(Student::getId, Function.identity()));
Map<Long, Person> peopleById2 = toMapBy(students, Student::getId); // compile error!
В этом примере Student
является подтипом Person
и имеет метод getId
, который возвращает Long
.
Последний оператор не работает с incompatible types: inference variable T has incompatible bounds ...
(JDK 1.8.0_25). Есть ли способ определить параметры типа, чтобы статический метод работал в тех же контекстах, что и содержащееся выражение?