提问者:小点点

此处不需要方法引用表达式,编译时错误


我正在使用stream来迭代列表,并希望在映射中收集它,但得到编译时错误:

此处不需要方法引用表达式

这是我的代码

List<Person> personList = getPersons();
Map<String, Integer> personAgeMap = personList.stream()
       .collect(Collectors.toMap(Person::getFirstName + "_" + Person::getLastName, Person::getAge));

我已经检查了这些答案:

>

  • 此处不需要Java方法引用

    使用方法引用了解编译时错误

    但这些都不是我要找的,我也看到了方法引用类型。

    在这种情况下,它是实例类型的实例方法,我怎么能在收集器中有Person的实例。

    可能的解决方案是什么,或者它是可行的方式?


  • 共3个答案

    匿名用户

    你不能这样做,这没有意义:

    Collectors.toMap(Person::getFirstName + "_" + Person::getLastName
    

    您需要了解toMap方法的签名是什么。 为了简单起见,我们假设它是:

    void toMap(Function<? super T,? extends K> keyMapper)
    

    你看? keyMapper是Function类型的对象。 该函数接受一个输入(一个人)并返回一个输出(一个字符串)。 所以你需要提供一个函数来完成这个任务。 如果你写

    Person::getFirstName + "_" + Person::getLastName
    

    那就是。。。 好吧,没什么,但让我们假设在最坏的情况下,它可能是一个字符串。 因为你用一个字符串连接了3个东西。 这不是函数。 你想要的是创建一个函数。

    所以你可以这样做:

    Collectors.toMap(new Function<Person, String>() {
       public String apply(Person person) {
          return person.getFirstName() + "_" + person.getLastName();
       }
    });
    

    简写为:

    Collectors.toMap(person -> person.getFirstName() + "_" + person.getLastName()
    

    匿名用户

    方法引用用于在lambda中重新引用方法。 它不调用方法,而是提供对lambda的引用。

    这意味着您不能以调用方法的方式使用方法引用,因此Person::GetFirstName+“_”+Person::GetLastName是不正确的。

    因此,为了得到您想要的结果,您可以使用基本的lambda表达式,如下所示:

    List<Person> personList = getPersons();
    Map<String, Integer> personAgeMap = personList.stream()
                                          .collect(Collectors.toMap(person -> person.getFirstName() + "_" + person.getLastName(), Person::getAge));
    

    希望我有用。

    匿名用户

    不能在其中使用方法引用。 试试lambda吧。

    Collectors.toMap(
        p -> String.format("%s_%s", p.getFirstName(), p.getLastName()), 
        Person::getAge
    )
    

    Person::GetFirstNamePerson::GetLastName都是某些函数接口的实例(从不属于String),例如SupplierFunction,运算符+不能应用于它们。

    同样,如果你是

    Object o = new Object() + new Object();
    

    让你有点迷惑

    p -> ((Function<Person, String>) Person::getFirstName).apply(p) + "_" + 
         ((Function<Person, String>) Person::getLastName).apply(p)