Как рассчитать маску с использованием потока java - PullRequest
8 голосов
/ 16 июня 2020

У меня есть этот код. Здесь карта 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));
  }
}

Я хочу рассчитать маску с использованием потока Java. Здесь я попытался получить только тогда список фильтров. Не знаю, как рассчитать маску здесь.

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

Ответы [ 4 ]

12 голосов
/ 16 июня 2020

Вы можете сопоставить свою запись с вычисленным значением, а затем применить or в операторе сокращения:

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

Изменить: добавлен 0 в качестве элемента идентификации для операции сокращения, чтобы иметь значение по умолчанию 0, если карта пуста.

Edit2: как было предложено в комментариях, я изменил порядок фильтров, чтобы избежать ненужных вызовов методов

Edit3: как было предложено в комментариях, теперь используется mapToInt

6 голосов
/ 16 июня 2020

Вы можете попробовать это, но, как сказал выше Аникет, mask мутирует, не рекомендуется использовать Strem.

map.entrySet().filter( entry -> entry.getKey().getValue() > 0 && entry.getValue()).forEach(k->{mask=mask | (1 << (k.getKey().getValue() - 1))});
4 голосов
/ 16 июня 2020

Вот еще одна альтернатива.

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)));
2 голосов
/ 16 июня 2020

Подобно это , но здесь сокращение написано другим способом, указывающим, что оно должно начинаться с 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);

Как было указано в комментариях, вы можете выполнить дальнейшее разложение в таким образом:

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