1

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...?

2 Answers 2

4

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())
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. No idea how I didn't see this myself... I guess I had some tunnel vision due to the ridiculous fact that isInfinite has a non-static version and isFinite doesn't...
3

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.