Потоки Java8 с картой? - PullRequest
2 голосов
/ 29 мая 2019

У меня есть следующая карта (каждый ключ String и каждое значение List<Message>)

Мой map выглядит следующим образом:

1st entry :"MONDAY" -> [message1, message2, message3]
2nd entry : "TUESDAY" -> [message4, message5]
...

Моя цельэто изменить содержимое каждого сообщения:

Я думал об этом:

map.entrySet().stream().peek(entry -> {
    entry.getValue().stream().peek(m -> m.setMessage(changeMessage()))
})

Но не знаю, как закончить и сделать это правильно.

Ответы [ 3 ]

2 голосов
/ 29 мая 2019

К сожалению, не обеспечивает простой способ изменить Map значения без нарушения Побочные эффекты принцип:

Побочные эффекты в поведенческих параметрах для потоковых операций, как правило, не приветствуются, поскольку они часто могут привести к невольным нарушениям требования о безгражданстве, а также другим угрозам безопасности потоков.

Вот возможное решение:

Map<String, List<Message>> = map.entrySet().stream()
    .map(e -> {                                                      // iterate entries
            e.setValue(e.getValue().stream()                         // set a new value
                .map(message -> {
                    message  -> message.setMessage(changeMessage()); // .. update message
                    return message;})                                // .. use it
                .collect(Collectors.toList()));                      // return as a List
            return e;})                                              // return an updated value
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));      // collec to a Map

Тем не менее, Java предоставляет хорошо известную функцию for-each для достижения вашей цели более прямым способом, который более читабелен:

for (List<Message> list: map.values()) { 
    for (Message message: list) { 
        message.setMessage(changeMessage()); 
    } 
}
0 голосов
/ 29 мая 2019

Если вы просто хотите обновить message всех сообщений, нет необходимости использовать весь набор записей. Вы можете просто передавать значения вашей карты и отображать элементы. Используйте forEach() для их обновления:

map.values().stream().flatMap(List::stream)
        .forEach(m -> m.setMessage(changeMessage(m.getMessage())));

Если вам нужен ключ для изменения сообщения, вы можете использовать это:

map.forEach((key, messages) -> messages.forEach(m -> 
        m.setMessage(changeMessage(key, m.getMessage()))));
0 голосов
/ 29 мая 2019

Итерируйте карту, измените каждый элемент списка снова, поместите собранный список в тот же ключ карты.

map.forEach((k,v)->{
                map.put(k, v.stream().map(i->i+"-changed").collect(Collectors.toList()));

            });
...