RookieGuy
RookieGuy

Reputation: 517

Java Stream Api - good ways to operate on Map<String, Double>?

I want to do some calculations with weighted averages. There are two maps

Map<String, Double> weightedVector;
Map<String, Double> otherVector;

The pseudo algorithm is like this

foreach entry in weightedVector:
  get same entry from otherVector 
  - if it exists then multiply weights and add new entry to another map
  - otherwise do nothing

I want to take advantage of the Stream API and came up with this

Stream<Double> map = weightedVector.entrySet().parallelStream()
.map(entry -> {
    Double t = otherVector.get(entry.getKey());
    Double v = entry.getValue();
    return (t != null && v != null) 
            ? t * v 
            : 0.0;
});

One question I ask myself whether it is good practice to use the old-style in order to access otherVector like in the snippet above.

The main problem for me is that I have two input maps and want to get an output map of the same type but the code above gets me a Stream of Double from the calculation.

Am I better off using stream().collect(..), then how?

Is it maybe better to not use the HashMap but rather create a container object containing the key-value pair and use that instead?

Upvotes: 2

Views: 1640

Answers (2)

Tunaki
Tunaki

Reputation: 137074

If you can modify the map in-place then you could also loop over the otherVector entries and update the weightedVector map accordingly:

otherVector.forEach((key, t) -> weightedVector.computeIfPresent(key, (k, v) -> t * v));

This will compute the product of the otherVector and weightedVector values for each key in otherVector.

Upvotes: 2

JB Nizet
JB Nizet

Reputation: 691705

Assuming you actually want to do nothing when there is no corresponding entry:

Map<String, Double> result = 
        weightedVector.entrySet()
                      .stream()
                      .filter(e -> otherVector.containsKey(e.getKey()))
                      .collect(Collectors.toMap(
                          Map.Entry::getKey,
                          e -> e.getValue() * otherVector.get(e.getKey())));

Upvotes: 2

Related Questions