英文:
Collectors.maxBy(Comparator.naturalOrder()) doesn't compile although Long is inferred
问题
以下是您提供的代码的翻译部分:
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())))); // 无法与此代码一起工作
Map<String, Optional<Long>> mapCorrect = list.stream()
.collect(Collectors.groupingBy(
c -> c.getOutput().getType(),
Collectors.mapping(
Container::getDifference,
Collectors.maxBy(Comparator.comparingLong(l -> l))))); // 修复此处以解决问题
对象的定义(包括全参数构造函数和获取方法):
public class Container<T> {
T output;
long difference;
}
public class Dto {
String type;
}
注意,这个问题可以在 OpenJDK 的 jdk-11.0.5
和 jdk1.8.0_212
版本中重现。我使用 IntelliJ Idea,这个IDE不会突出显示这种错误,但会在编译时引发错误。
英文:
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<T> 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.
答案1
得分: 7
标准的Oracle / OpenJDK编译器版本8至14的推理引擎无法正确跟踪发生的情况。
然而,Eclipse的编译器可以,这就是为什么其他人说他们无法重现这个问题。
您需要通过指定以下方式来帮助它:
Collectors.maxBy(Comparator.<Long>naturalOrder())))); // 现在可以工作
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论