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...
Basically to pass a lamda expression as a parameter, we need a type in which we can hold it. Just as an integer value we hold in primitive int or Integer class. Java doesn't have a separate type for lamda expression instead it uses an interface as the type to hold the argument.
Yes, any lambda expression is an object in Java.
In order to match a lambda to a single method interface, also called a "functional interface", several conditions need to be met: The functional interface has to have exactly one unimplemented method, and that method (naturally) has to be abstract.
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.
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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With