英文:
Collectors.toMap with method reference compiles but not with identity function lambda
问题
下面的语句给我一个错误,但另一种形式可以工作,有什么区别
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-> x, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
下面的可以工作
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, Employee::getId, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
英文:
I have an ArrayList
which I'm trying to convert to a LinkedHashMap. The below statement gives me an error but another form works what is the difference
Below give an error Bad return type in lambda expression: U cannot be converted to Employee
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-> x, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
Below work
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, Employee::getId, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
答案1
得分: 1
Collectors.toMap
的前两个参数分别是键映射器和值映射器。
keyMapper = Employee::getName
等同于 keyMapper = x -> x.getName()
,意味着结果映射的键将是员工的名称属性(String)。
valueMapper = x -> x
意味着结果映射的值将是员工本身。只有当结果类型为 LinkedHashMap<String, Employee>
而不是 LinkedHashMap<String, Integer>
时才可能成功,这也是为什么它失败的原因。
valueMapper = Employee::getId
等同于 valueMapper = x -> x.getId()
,意味着结果映射的值将是员工的id属性(Integer)。这与结果类型 LinkedHashMap<String, Integer>
兼容。
也就是说,根据预期的结果,以下两种方式都是正确的:
// 从名称映射到员工
LinkedHashMap<String, Employee> collect = employees.stream()
.sorted(Comparator.comparing(Employee::getName).reversed())
.collect(Collectors.toMap(x -> x.getName(), x -> x, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
// 从名称映射到员工ID
LinkedHashMap<String, Integer> collect = employees.stream()
.sorted(Comparator.comparing(Employee::getName).reversed())
.collect(Collectors.toMap(Employee::getName, Employee::getId, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
英文:
The first two arguments of the Collectors.toMap
are a key mapper and a value mapper, respectively.
keyMapper = Employee::getName
is equivalent to keyMapper = x -> x.getName()
and means that the key of the resulting map will be the name attribute of the employee (String).
valueMapper = x -> x
means that the value of the resulting map will be the employee itself. That would only be possible if the result was of type LinkedHashMap<String, Employee>
instead of LinkedHashMap<String, Integer>
, and that's why it fails.
valueMapper = Employee::getId
is equivalent to valueMapper = x -> x.getId()
and means that the value of the resulting map will be the id attribute of the employee (Integer). This is compatible with the result type LinkedHashMap<String, Integer>
.
That said, both the below are correct depending on the intended outcome:
// map from name to Employee
LinkedHashMap<String, Employee> collect = employees.stream()
.sorted(Comparator.comparing(Employee::getName).reversed())
.collect(Collectors.toMap(x -> x.getName(), x -> x, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
// map from name to Employee Id
LinkedHashMap<String, Integer> collect = employees.stream()
.sorted(Comparator.comparing(Employee::getName).reversed())
.collect(Collectors.toMap(Employee::getName, Employee::getId, (oldValue, newValue) -> oldValue, LinkedHashMap::new));
答案2
得分: 0
显然这段代码应该是:
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x -> x.getId(), (oldValue, newValue) -> old, LinkedHashMap::new));
注意区别在于 x-> x.getId()
而不是 x-> x
。
英文:
obviously this:
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-> x, (oldValue, newValue) -> old, LinkedHashMap::new));
should be
LinkedHashMap<String, Integer> collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-> x.getId(), (oldValue, newValue) -> old, LinkedHashMap::new));
note the x-> x.getId()
difference insead of x-> x
答案3
得分: 0
查看Collection.toMap
函数定义,来自docs.oracle的链接:
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function-java.util.function.BinaryOperator-java.util.function.Supplier-
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
。
如果您想创建一个LinkedHashMap<String, Integer>
,那么valueMapper
应该提供一个Integer
类型的对象,但在第一个示例中x->x
并不是这种情况,它是一个接受Employee
对象并返回一个Employee
的lambda表达式。而Employee::getId
可以正常工作,因为它返回了正确类型的对象,即Integer
。
英文:
taking a look to the function definition of Collection.toMap
from docs.oracle:
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toMap-java.util.function.Function-java.util.function.Function-java.util.function.BinaryOperator-java.util.function.Supplier-
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
.
Since you want to create a LinkedHashMap<String, Integer>
than the valueMapper
should provide an object of type Integer
which is not the case in the first example x->x
which is a lambda taking an Employee
object and returns an Employee
as well, whereas Employee::getId
works fine since it returns an object of the correct type which is Integer
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论