I have the following code:
class Result {
public Result(long infiniteCount, DoubleSummaryStatistics statistics) {
this.infiniteCount = infiniteCount;
this.statistics = statistics;
}
final long infiniteCount;
final DoubleSummaryStatistics statistics;
}
This compiles:
Result result = DoubleStream.of(1.0, 2.0, 3.0).boxed().collect(Collectors.teeing(
Collectors.filtering(Double::isFinite, Collectors.counting()),
Collectors.filtering(Double::isFinite, Collectors.summarizingDouble(d -> d)),
Result::new));
This doesn't:
Result result = DoubleStream.of(1.0, 2.0, 3.0).boxed().collect(Collectors.teeing(
Collectors.filtering(Double::isInfinite, Collectors.counting()),
Collectors.filtering(Double::isFinite, Collectors.summarizingDouble(d -> d)),
Result::new));
Compilation results in this:
java: incompatible types: cannot infer type-variable(s) T,A,R,capture#1 of ?,T (argument mismatch; invalid method reference reference to isInfinite is ambiguous both method isInfinite(double) in java.lang.Double and method isInfinite() in java.lang.Double match)
Here is the source code of these 2 methods from Double.java of Java 19... I don't understand why is there difference... (AFAIK @IntrinsicCandidate
shouldn't affect this, and otherwise it's just two methods that return a boolean).
@IntrinsicCandidate
public static boolean isInfinite(double v) {
return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);
}
public static boolean isFinite(double d) {
return Math.abs(d) <= Double.MAX_VALUE;
}
So, why does the first compile and the second doesn't...?
CodePudding user response:
You are missing the non-static Double.isInfinite()
method:
public boolean isInfinite() {
return isInfinite(value);
}
This makes Double::isInfinite
ambiguous as both methods match. You could use a lambda to disambiguate it:
Collectors.filtering(d -> d.isInfinite(), Collectors.counting())
CodePudding user response:
isInfinite
exists as static and instance method:
static boolean isInfinite(double d)
boolean isInfinite()
Your method reference becomes ambiguous. By converting to a lambda, you can disambiguate:
Result result = DoubleStream.of(1.0, 2.0, 3.0).boxed().collect(Collectors.teeing(
Collectors.filtering(d -> d.isInfinite(), Collectors.counting()),
Collectors.filtering(Double::isFinite, Collectors.summarizingDouble(d -> d)),
Result::new));