-1

I know they have same effect, but why does Integer::intValue give an error?

public class ResistorColorDuo {
    Map<String, Integer> colValueMap;

    public ResistorColorDuo(Map<String, Integer> colValueMap) {
        colValueMap.put("Black", 0);
        colValueMap.put("Brown", 1);
        colValueMap.put("Red", 2);
        colValueMap.put("Orange", 3);
        colValueMap.put("Yellow", 4);
        colValueMap.put("Green", 5);
        colValueMap.put("Blue", 6);
        colValueMap.put("Violet", 7);
        colValueMap.put("Grey", 8);
        colValueMap.put("White", 9);

        this.colValueMap = colValueMap;
    }

    public int getResistorValue(String... colors) {
        return Arrays.stream(colors).map(i -> colValueMap.get(i) *
                Math.pow(10, colors.length - (Arrays.asList(colors).indexOf(i) + 1)))
                .mapToInt(Integer::intValue) // Here occurs an exception
                .sum();
    }
}

Above code generated an error:

None-static method can not be referenced from a static context

While it works well like this:

public int getResistorValue(String... colors) {
    return Arrays.stream(colors).map(i -> colValueMap.get(i) *
            Math.pow(10, colors.length - (Arrays.asList(colors).indexOf(i) + 1)))
            .mapToInt(Integer -> Integer.intValue())
            // Here is the difference
            .sum();
}
Ivar
  • 6,138
  • 12
  • 49
  • 61

1 Answers1

6

I'm not sure the error message you got is very informative (see the error message I got below). However, in your map step you are returning the result of Math.pow(), which is double. Hence your Stream becomes a Stream<Double>.

Trying to apply .mapToInt(Integer::intValue) fails, because Integer's intValue() requires an Integer instance.

When you use the lambda expression mapToInt(Integer -> Integer.intValue()), you should note that Integer is just the lambda parameter name, so it would have been less confusing to write mapToInt(n -> n.intValue()). Since n is a Double in this case, that lambda expression actually executes Double's intValue(), which works.

For a method reference to work, you need to use .mapToInt(Double::intValue).

EDIT: I tried similar code (I didn't feel like typing all the code from your image):

int sum = Stream.of ("1","2","3")
                .map (Integer::valueOf)
                .map(i -> Math.pow(i,2))
                .mapToInt(Integer::intValue)
                .sum();

and got a much better compilation error message:

The type Integer does not define intValue(Double) that is applicable here

This is fixed by changing the method reference as follows:

int sum = Stream.of ("1","2","3")
                .map (Integer::valueOf)
                .map(i -> Math.pow(i,2))
                .mapToInt(Double::intValue)
                .sum();
Eran
  • 387,369
  • 54
  • 702
  • 768