How to calculate mask using java stream

Viewed 361

I have this code. Here the map is Map<Data, Boolean>

int mask = 0;
for (Map.Entry<Data, Boolean> entry : map.entrySet()) {
  if (entry.getKey().getValue() > 0 && entry.getValue()) {
    mask = mask | (1 << (entry.getKey().getValue() - 1));
  }
}

I want to calculate mask using Java stream. Here I tried to but only get then filter list. Don't know how calculate the mask here.

Integer mask = map.entrySet().filter( entry -> entry.getKey().getValue() > 0 && entry.getValue()).?
4 Answers

You can map your entry to the calculated value and then apply the or within a reduce operator:

map.entrySet().stream()
       .filter(entry -> entry.getValue() && entry.getKey().getValue() > 0)
       .mapToInt(entry -> (1 << (entry.getKey().getValue() - 1)))
       .reduce(0, (r, i) -> r | i)

Edit: Added 0 as identity element to the reduce operation to have a default value of 0 if the map is empty.

Edit2: As suggested in the comments I reversed the filter order to avoid unnecessary method calls

Edit3: As suggested in the comments mapToInt is now used

You can try this , but as Aniket said above here mask is mutating not a good idea to use Strem.

map.entrySet().filter( entry -> entry.getKey().getValue() > 0 && entry.getValue()).forEach(k->{mask=mask | (1 << (k.getKey().getValue() - 1))});

Here is yet another alternative.

int mask = map.entrySet().stream().filter(Entry::getValue)
            .mapToInt(e -> e.getKey().getValue()).filter(a -> a > 0)
            .reduce(0, (a, b) -> a | (1<<(b-1)));

Similar to this but here reduce is written in other way indicated that it should start from 0.

map.entrySet().stream()
    .filter(entry -> entry.getKey().getValue() > 0 && entry.getValue())
    .map(entry -> (1 << (entry.getKey().getValue() - 1)))
    .reduce(0, (a, v) -> a | v);

As it was maintained in comments you can do further decomposition it in this way:

map.entrySet().stream()
    .filter(Map.Entry::getValue)
    .map(entry -> entry.getKey().getValue())
    .filter(keyValue -> keyValue > 0)
    .map(keyValue -> (1 << (keyValue - 1)))
    .reduce(0, (a, v) -> a | v);
Related