Mateusz Budzisz
Mateusz Budzisz

Reputation: 729

Why does using a method reference instead of a lambda result in a compile error in this case?

I have the following code:

final var fieldValuesStream = items.stream()
                .map(person -> PersonFieldGetter.getFieldValueAsNumber(functionsParameters.getFieldName(), person)) // Number
                .mapToDouble(number -> number.doubleValue());

IDEA highlights "number -> number.doubleValue()" with the message:

Lambda can be replaced with method reference
Replace Lamda with method reference

But when I change the code to .mapToDouble(Number::doubleValue) a compile error happens:

QueryProcessor.java:31:34 java: incompatible types: invalid method reference method doubleValue in class java.lang.Number cannot be applied to given types required: no arguments found: java.lang.Object reason: actual and formal argument lists differ in length

Full source code
Why is this happening?

Project to reproduce the problem

EDIT: Added link to GitHub project with example project that is failing to build using:

IntelliJ IDEA 2021.2.3 (Ultimate Edition)
Build #IU-212.5457.46, built on October 12, 2021
Runtime version: 11.0.12+7-b1504.40 amd64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
SDK: Oracle OpenJDK 17.0.1

Upvotes: 8

Views: 392

Answers (1)

samabcde
samabcde

Reputation: 8124

Not an answer, aiming to provide a simplified reproducible example for other to solve the problem.

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List.of(0.1d).stream().map(aDouble -> {
                    return List.of(1).stream().map(p -> aDouble).mapToDouble(Number::doubleValue);
                }
        );
    }
}

Seems the problem is the compiler can't recognize the type of aDouble in the nested stream and cause some strange error.

Some way to make it compiles

  1. Remove return
        Stream.of(0.1d).map(aDouble ->
                List.of(1).stream().map(p -> aDouble).mapToDouble(Double::doubleValue)
        );
  1. Specify type of aDouble
        Stream.of(0.1d).map((Double aDouble) -> {
                    return List.of(1).stream().map(p -> aDouble).mapToDouble(Double::doubleValue);
                }
        );
  1. Not use method reference
        Stream.of(0.1d).map(aDouble -> {
                    return List.of(1).stream().map(p -> aDouble).mapToDouble(d -> d.doubleValue());
                }
        );

Upvotes: 2

Related Questions