You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java8中使用Function::identity于Collectors.toMap时出现参数不匹配错误

问题:用Collectors.toMap时,Function::identity为啥会编译报错?

我有一个简单的Person POJO类:

public class Person {
    private String id;
    private String name;

    public Person(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }
}

我想把一个List<Person>转换成Map<String, Person>,其中key是Person的id属性。于是我写了下面的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class CollectorMain {
    public static void main(String[] args) {
        List<Person> list = new ArrayList<>();
        list.add(new Person("312", "John"));
        list.add(new Person("454", "Alice"));
        list.add(new Person("712", "Bob"));

        Map<String, Person> map = list.stream()
                .collect(
                    Collectors.toMap(Person::getId, Function::identity) // 这里编译报错
                );

        System.out.println(map.size());
    }
}

结果出现了编译错误,错误信息如下:

CollectorMain.java:[14,41] no suitable method found for toMap(Person::getId,Function::identity)
    method java.util.stream.Collectors.<T,K,U>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>) is not applicable
      (cannot infer type-variable(s) T,K,U
        (argument mismatch; incompatible parameter types in method reference))
    method java.util.stream.Collectors.<T,K,U>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>,java.util.function.BinaryOperator<U>) is not applicable
      (cannot infer type-variable(s) T,K,U
        (actual and formal argument lists differ in length))
    method java.util.stream.Collectors.<T,K,U,M>toMap(java.util.function.Function<? super T,? extends K>,java.util.function.Function<? super T,? extends U>,java.util.function.BinaryOperator<U>,java.util.function.Supplier<M>) is not applicable
      (cannot infer type-variable(s) T,K,U,M
        (actual and formal argument lists differ in length))

我知道把Function::identity换成lambda表达式p -> p就能解决问题:

Map<String, Person> map = list.stream()
        .collect(
            Collectors.toMap(Person::getId, p -> p)
        );

那有没有办法用Function::identity来实现这个需求呢?


当然可以!问题出在类型推断上

编译器在这里没法自动推断出Function::identity的泛型类型,因为Collectors.toMap的两个参数需要关联同一个输入类型T(也就是Person),但方法引用Function::identity本身是无界的,编译器没法确定它应该接受Person类型的输入。

解决方法就是显式指定泛型类型,有两种方式:

方式一:给Collectors.toMap指定泛型参数

显式声明toMap的三个泛型参数:T=Person,K=String,U=Person:

Map<String, Person> map = list.stream()
        .collect(
            Collectors.<Person, String, Person>toMap(Person::getId, Function::identity)
        );

方式二:给Function.identity()指定泛型参数

直接给identity方法指定泛型,明确它返回的是Person类型的Function:

Map<String, Person> map = list.stream()
        .collect(
            Collectors.toMap(Person::getId, Function.<Person>identity())
        );

这样编译器就能正确识别类型,编译就不会报错了。


内容的提问来源于stack exchange,提问作者Jmini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:03:34