Reputation: 1313
I have the following Map (each key is a String
and each value is a List<Message>
)
My map
is like this :
1st entry :"MONDAY" -> [message1, message2, message3]
2nd entry : "TUESDAY" -> [message4, message5]
...
My goal is to change each message content :
I was thinking about this :
map.entrySet().stream().peek(entry -> {
entry.getValue().stream().peek(m -> m.setMessage(changeMessage()))
})
But don't know how to finish and do it properly.
Upvotes: 2
Views: 100
Reputation: 44496
Unfortunately, java-stream doesn't provide a straightforward way to change the Map
values without violating the Side-effects principle:
Side-effects in behavioral parameters to stream operations are, in general, discouraged, as they can often lead to unwitting violations of the statelessness requirement, as well as other thread-safety hazards.
Here is a possible solution:
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
However, Java provides a well-known for-each
feature to achieve your goal in a more direct way which is more readable:
for (List<Message> list: map.values()) {
for (Message message: list) {
message.setMessage(changeMessage());
}
}
Upvotes: 2
Reputation: 11050
If you just want to update the message
of all messages there is no need to use the whole entry set. You can just stream the values of your map and map the items. The use forEach()
to update them:
map.values().stream().flatMap(List::stream)
.forEach(m -> m.setMessage(changeMessage(m.getMessage())));
If you need the key to change the message you can use this:
map.forEach((key, messages) -> messages.forEach(m ->
m.setMessage(changeMessage(key, m.getMessage()))));
Upvotes: 0
Reputation: 101
Iterate map, change each element of list again put the collected list on the same key of the map.
map.forEach((k,v)->{
map.put(k, v.stream().map(i->i+"-changed").collect(Collectors.toList()));
});
Upvotes: 0