Home > database >  How is Double::isFinite different from Double::isInfinite?
How is Double::isFinite different from Double::isInfinite?

Time:12-28

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));
  • Related