我有以下 map (每个键是 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()))
})
但不知道如何完成并正确完成。
最佳答案
不幸的是,java-stream没有提供一种在不违反 Side-effects 的情况下更改 Map
值的简单方法。原理:
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.
这是一个可能的解决方案:
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());
}
}
关于Java8 与 Map 进行流传输?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56360204/