Как передать карту с коллекцией с использованием потоков Java 8 - PullRequest
0 голосов
/ 16 сентября 2018

Я бы хотел передать карту с коллекцией, используя потоки Java 8.

Например, имея следующие данные:

Map<String, Collection<Integer>> data;

Я хотел бы просмотреть элементыобработка каждого целочисленного значения с соответствующими строками ключа.Например:

data.keyValueStream((k,v)-> ...)

Есть идеи, как этого добиться?Спасибо.

* Что касается вопроса «Зачем вам это нужно?», Это может быть несколько причин, и я не уверен, что это важно.Во всяком случае, я буду «течь» с вами ... Мой конкретный сценарий заключается в пакетной вставке в БД всех значений под их конкретным ключом.Давайте оставим общий вопрос о потоке Java 8 ...

Ответы [ 4 ]

0 голосов
/ 16 сентября 2018

Хотя это может быть немного очевидно, вы также можете написать:

map.forEach((k, v) -> v.forEach(s -> System.out.println(k + "  " + s)))

Пример, на Java 9.

Map< String , Collection< Integer > > map =
    Map.ofEntries(
        Map.entry( "alpha" , List.of( 1 , 2 , 3 ) ) ,
        Map.entry( "beta" , List.of( 4 , 5 , 6 ) ) ,
        Map.entry( "gamma" , List.of( 7 , 8 , 9 ) )
    )
;

map.forEach( ( k , v ) -> {
        v.forEach( s -> System.out.println( k + "  " + s ) );
    }
);
0 голосов
/ 16 сентября 2018

Потоковая обработка обрабатывает только одно значение, поэтому вы не можете получить keyValueStream((k,v)-> ...), но вы можете получить keyValueStream(x -> ...), где x - это кортеж / пара.

Поскольку вы начинаете с Map, который может передавать Entry объекты (пары ключ / значение), и вам нужна пара ключ / значение в вашей лямбде, поток Entry объектов кажется подходящим.

Это означает, что вы просто хотите сгладить вложенную коллекцию, например, как это:

import java.util.AbstractMap.SimpleEntry;
data.entrySet()
    .stream()
    .flatMap(e -> e.getValue().stream().map(v -> new SimpleEntry<>(e.getKey(), v)))
    // At this point you have a Stream<Entry<String, Integer>> so you can e.g. do this:
    .forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()))
;
0 голосов
/ 16 сентября 2018

Я понимаю, что вы спрашиваете о потоковой версии, но , если вы НЕ собираетесь использовать параллелизм Самый простой и, вероятно, более эффективный вариант - это использование вложенных циклов. Таким образом, вы можете избежать затрат времени и места на создание временных экземпляров для каждой пары <Key,CollectionItem>.

Вместо этого вы можете использовать

for (Map.Entry<String, Collection<Integer>> entry : map.entrySet()){
    String key = entry.getKey();
    for (Integer number : entry.getValye()){
        //here we have access to <key, number> pair, 
        //handle them as you wish;
    }
}
0 голосов
/ 16 сентября 2018

Вы можете сопоставить свой Map<String, Collection<Integer>> с List<Map.Entry<String, Integer>>:

data.entrySet().stream()
  .flatMap(e -> e.getValue().stream().map(v -> new HashMap.SimpleEntry<>(e.getKey(), v)))
  .forEach(e -> System.out.printf("key %s val %d%n", e.getKey(), e.getValue()));

или

data.forEach((k, v) -> v.forEach(n -> System.out.printf("key %s val %d%n", k, n)));
...