Why Collectors.groupingBy gets confused with identity function?

I'm trying to count occurrences of integers in an array using Collectors.groupingBy from Java 8 API but I'm getting some strange compilation errors.

Here is my code:

List<Integer> l = Arrays.asList(1, 1, 1, 2, 3, 3, 3, 3);
Map<Integer, Integer> x = l.stream().collect(groupingBy(i -> i, counting()));

Sadly, this won't compile, resulting in the following error:

error: incompatible types: inferred type does not conform to equality constraint(s)
        Map<Integer, Integer> x = l.stream().collect(groupingBy(i -> i, counting()));
                                                    ^
    inferred: Integer
    equality constraints(s): Integer,Long
1 error

It seems to be a generic type issue, because when I remove the generic Map type, it compiles. Here is another test:

List<Integer> l = Arrays.asList(1, 1, 1, 2, 3, 3, 3, 3);
Map x = l.stream().collect(groupingBy(i -> i, counting()));

System.out.println(x);

And the output is right as expected:

{1=3, 2=1, 3=4}

Any ideas of how to solve that without the need of casting all the types here and there?

Jon Skeet
people
quotationmark

counting() is declared as:

static <T> Collector<T,?,Long>

... whereas you're trying to use it as if it produces an Integer.

If you change your code to:

Map<Integer, Long> x = l.stream().collect(groupingBy(i -> i, counting()));

... it will compile with no problems. Note that in your current code using the raw type, your output actually has Long values rather than Integer values... it's just you can't tell that from the string representation.

people

See more on this question at Stackoverflow