Collectors.toMap 使用方法引用编译通过,但使用 identity 函数的 Lambda 不编译。

huangapple go评论65阅读模式
英文:

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&lt;String, Integer&gt; collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-&gt; x, (oldValue, newValue) -&gt; oldValue, LinkedHashMap::new));

Below work

 LinkedHashMap&lt;String, Integer&gt; collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, Employee::getId, (oldValue, newValue) -&gt; 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 -&gt; x.getName() and means that the key of the resulting map will be the name attribute of the employee (String).

valueMapper = x -&gt; 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&lt;String, Employee&gt; instead of LinkedHashMap&lt;String, Integer&gt;, and that's why it fails.

valueMapper = Employee::getId is equivalent to valueMapper = x -&gt; 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&lt;String, Integer&gt;.

That said, both the below are correct depending on the intended outcome:

// map from name to Employee
LinkedHashMap&lt;String, Employee&gt; collect = employees.stream()
        .sorted(Comparator.comparing(Employee::getName).reversed())
        .collect(Collectors.toMap(x -&gt; x.getName(), x -&gt; x, (oldValue, newValue) -&gt; oldValue, LinkedHashMap::new));

// map from name to Employee Id
LinkedHashMap&lt;String, Integer&gt; collect = employees.stream()
        .sorted(Comparator.comparing(Employee::getName).reversed())
        .collect(Collectors.toMap(Employee::getName, Employee::getId, (oldValue, newValue) -&gt; 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&lt;String, Integer&gt; collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-&gt; x, (oldValue, newValue) -&gt; old, LinkedHashMap::new));

should be

LinkedHashMap&lt;String, Integer&gt; collect = employees.stream().sorted(Comparator.comparing(Employee::getName).reversed()).collect(Collectors.toMap(Employee::getName, x-&gt; x.getId(), (oldValue, newValue) -&gt; old, LinkedHashMap::new));

note the x-&gt; x.getId() difference insead of x-&gt; 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&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper, BinaryOperator&lt;U&gt; mergeFunction, Supplier&lt;M&gt; mapSupplier)

如果您想创建一个LinkedHashMap&lt;String, Integer&gt;,那么valueMapper应该提供一个Integer类型的对象,但在第一个示例中x-&gt;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&lt;? super T,? extends K&gt; keyMapper, Function&lt;? super T,? extends U&gt; valueMapper, BinaryOperator&lt;U&gt; mergeFunction, Supplier&lt;M&gt; mapSupplier).

Since you want to create a LinkedHashMap&lt;String, Integer&gt; than the valueMapper should provide an object of type Integer which is not the case in the first example x-&gt;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 .

huangapple
  • 本文由 发表于 2023年2月10日 05:17:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404489.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定