I cannot compile the following piece of code (try at onlinegdb):
List<Container<Dto>> list = Arrays.asList(
new Container<>(new Dto("A"), 10L),
new Container<>(new Dto("A"), 30L),
new Container<>(new Dto("B"), 30L));
Map<String, Optional<Long>> mapWrong = list.stream()
.collect(Collectors.groupingBy(
c -> c.getOutput().getType(),
Collectors.mapping(
Container::getDifference,
Collectors.maxBy(Comparator.naturalOrder())))); // DOESN'T WORK WITH THIS
incompatible types: cannot infer type-variable(s) T,U,A,R,capture#2 of ?,T,T (argument mismatch; invalid method reference method getDifference in class Container cannot be applied to given types required: no arguments found: java.lang.Object reason: actual and formal argument lists differ in length)
I have no idea what causes the compilation error. The Collectors.mapping
maps an object to a new value and since Container::getDifference
returns long
and the very same type should be inferred into Collectors.maxBy
and the code should get compiled.
Surprisingly, when I replace the Comparator.naturalOrder()
with Comparator.comparingLong(l -> l)
, then it works.
Map<String, Optional<Long>> mapCorrect = list.stream()
.collect(Collectors.groupingBy(
c -> c.getOutput().getType(),
Collectors.mapping(
Container::getDifference,
Collectors.maxBy(Comparator.comparingLong(l -> l))))); // A CHANGE TO FIX IT
The objects used (including all-args constructor and getters):
public class Container<T> {
T output;
long difference;
}
public class Dto {
String type;
}
Note this is reproducible using OpenJDK both jdk-11.0.5
and jdk1.8.0_212
. I use IntelliJ Idea and the IDE doesn't highligh such error, however raises it on compilation.
The inference engine of the standard Oracle / OpenJDK compiler, versions 8 to 14, cannot correctly track what is going on.
However, Eclipse's compiler can, which is why others say they cannot reproduce the issue.
You need to help it along by specifying:
Collectors.maxBy(Comparator.<Long>naturalOrder())))); // THIS NOW WORKS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With