Как выполнить потоковую передачу в java по карте key-> collection, где каждый поточный элемент является ключом, а каждый элемент коллекции? - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь сгладить карту, но не теряю ключ.

Что бы я хотел получить:

Map<K, Collection<V>> keyToValuesMap = ...;
Stream.flattenCollection(keyToValuesMap).forEach((k,v) -> print(k, v));

Где v представляет каждое значение в коллекции, соответствующеедля каждого k.


Эквивалентный код Java старой школы будет выглядеть следующим образом:

for (Map.Entry<K, Collection<V>> entry : keyToValuesMap.entrySet())
{
    K k = entry.getKey();

    for (V v : entry.getValue())
    {
         print(k, v);
    }
}

Обратите внимание, что этот вопрос отличается от простого потока по значениям,потому что key потерян, вот так: keyToValuesMap.entrySet().stream().flatMap(keyValuesEntry -> keyValuesEntry.getValue().stream()).forEach(v -> printJustV(v));

* print - это просто пример действия над парой.

* Я искал такой API в StreamEx , но не смог его найти.Я был уверен, что найду это там ...

Ответы [ 4 ]

0 голосов
/ 13 декабря 2018

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

Вы все еще можете просто создать вспомогательный метод где-нибудь в служебном классе:

public static <K, V> void forEachElement(
    Map<? extends K, ? extends Collection<? extends V>> map, 
    BiConsumer<? super K, ? super V> action
){
    for (Map.Entry<? extends K, ? extends Collection<? extends V>> entry : map.entrySet()){
        K k = entry.getKey();
        for (V v : entry.getValue()) {
             action.accept(k, v);
        }
    }
}

Что тогда можно назвать так:

SomeUtilClass.forEachElement(keyToValuesMap, (k, v) -> print(k, v));
0 голосов
/ 13 декабря 2018

Это было бы намного проще / компактно без потока:

map.forEach((k, v) -> v.forEach(e -> print(k, e)));
0 голосов
/ 13 декабря 2018
public static <K, V> void print(Map<K, Collection<V>> map) {
    map.entrySet().stream()
       .flatMap(entry -> entry.getValue().stream().map(value -> new AbstractMap.SimpleEntry<>(entry.getKey(), value)))
       .forEach(entry -> print(entry.getKey(), entry.getValue()));
}
0 голосов
/ 13 декабря 2018

Вы можете сохранить ключ, создав новый Entry s:

keyToValuesMap.entrySet()
              .stream()
              .flatMap(entry -> entry.getValue()
                                     .stream()
                                     .map(v -> new SimpleEntry(entry.getKey(),v)))
              .forEach(entry -> printEntry(entry));
...