【问题标题】:Java8 streams with Map?带有 Map 的 Java8 流?
【发布时间】:2019-10-15 01:04:08
【问题描述】:

我有以下 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()))
})

但不知道如何完成并正确完成。

【问题讨论】:

  • 还没有尝试过,但想知道使用简单的“forEach”是否更好,至少更容易。
  • My goal is to change each message content ,意思是..??请举例说明。
  • 试试这个map.forEach((k,v)->v.replaceAll(m->m.setMessage(changeMessage())));map.values().forEach(v->v.replaceAll(m->m.setMessage(changeMessage())));
  • 当你的意思是forEach时不要使用peek。当您只对values() 感兴趣时,不要使用entrySet()。显然,你只想做map.values() .forEach(list -> list.forEach(m -> m.setMessage(changeMessage())));

标签: java dictionary collections java-8 java-stream


【解决方案1】:

迭代地图,再次更改列表的每个元素,将收集到的列表放在地图的同一键上。

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

            });

【讨论】:

  • 是的,我在想这个:map.forEach((k,v) -> v.forEach(message -> message.setMessage("newValue")});
【解决方案2】:

不幸的是, 没有提供一种直接更改Map 值而不违反Side-effects 原则的方法:

通常不鼓励对流操作的行为参数产生副作用,因为它们通常会导致无意中违反无状态要求以及其他线程安全隐患。

这是一个可能的解决方案:

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()); 
    } 
}

【讨论】:

    【解决方案3】:

    如果您只想更新所有消息的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()))));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      相关资源
      最近更新 更多