9

I'm trying to stream a list of Doubles into a Map<Double, Double>, where the keys are the Doubles in the original list, and the values are some computed value.

This is what my code looks like:

// "values" is a List<Double> that was passed in
ImmutableMap<Double, Double> valueMap = values.parallelStream()
    .collect(Collectors.toMap(p -> p, p -> doThing(values, p)));

private Double doThing(List<Double>, Double p) {
    Double computedValue = 0.0;
    // Do math here with p
    return computedValue;
}

However, IntelliJ is complaining that p -> p is not a valid lambda expression - it's complaining about a cyclic inference. I'm also getting an error when I call doThing, because p is a lambda parameter and not a Double.

When I try to cast p to a Double in the call to doThing, that fails to cast.

Am I missing something really obvious? It seems like there's no way to actually do anything with my lambda parameters...

2 Answers 2

6

I think the problem here is simply that your collecting operation returns a Map<Double, Double> but the type of valueMap is ImmutableMap<Double, Double>.

You also forgot to give a name for the List<Double> parameter in doThing but I assume it was only a typo when writing the question.

Sign up to request clarification or add additional context in comments.

3 Comments

You're right about the typo, sorry about that. Changing it to a Map instead of an ImmutableMap seems to have fixed the problem. Do you know why the errors I saw were seemingly unrelated? For an error like that, I would have expected something like a type mismatch error between the return value of .collect() and the declared type of valueMap. Why in the world would a declared type mismatch cause a cyclic inference error...?
@sichinumi I tried it with Eclipse and got Type mismatch: cannot convert from Map<Object,Object> to ImmutableMap<Double,Double>. So the error you got is indeed a bit weird.
Afaik, IntelliJ uses javac just like Netbeans, so I can confirm that error messages connected to either Generics/Type Inference or Lambda Expressions can be confusing and far away from the actual problem. Sometimes, just a forgotten ), > or ; can cause plenty of absurd, unhelpful error messages.
1

As stated, the problem is that Collectors.toMap accumulates the element into Map<K,U> (the current implementation returns an HashMap but it's an internal detail).

If you want to collect into an ImmutableMap, you can use the collectingAndThen collector.

Use Collectors.toMap as the downstream collector and provide the function map -> ImmutableMap.copyOf(map) as a finisher.

ImmutableMap<Double, Double> valueMap = values.stream()
                .collect(collectingAndThen(toMap(p -> p, p -> doThing(values, p)), ImmutableMap::copyOf));

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.