【问题标题】:Java 8: Change the values of an EntrySet streamJava 8:更改 EntrySet 流的值
【发布时间】:2015-09-16 21:05:26
【问题描述】:

我有以下设置:

Map<Instant, String> items;
...
String renderTags(String text) {
    // Renders markup tags in a string to human readable form
}
...
<?> getItems() {
    // Here is where I need help
}

我的问题是,items 映射的值的字符串用标签标记。我希望getItems() 返回所有项目,但使用renderTags(String) 方法解析字符串。比如:

// Doesn't work
items.entrySet().stream().map(e -> e.setValue(renderTags(e.getValue())));

最有效的方法是什么?

【问题讨论】:

  • 你想让getItems()方法返回什么?
  • 这并不重要。一组条目会很棒,但是任何可以让我按返回顺序遍历它们的东西(它们存储在 TreeSet&lt;Instant, String&gt; 中,因此它们按时间顺序排列)。
  • 嗯,我认为您将 set 和 map 视为可互换的,实际上它们不同。一个集合基本上是一个布尔映射,一个映射通常不是一个集合。
  • @Vlasec 你当然是正确的。也许我该睡觉了。虽然只有 0215,所以我想我还能再呆几个小时......

标签: java dictionary java-8 java-stream


【解决方案1】:

另一种可能是

Map<Instant, String> getItems() {
return items.entrySet().stream()
           .peek(entry -> entry.setValue(renderTags(entry.getKey())))
           .collect(Collectors.toMap(Map.Entry::getKey,e -> e.getValue()));
}

如果您必须在对方付费电话之前对流执行更新,这很有用。

【讨论】:

  • 与接受的答案中显示的方式相比,这样做的优点/缺点是什么?
  • 它取决于上下文(不是问题之一)...我还没有使用 peek 方法,但我记住它存在。
  • 听起来不错。我经常使用它进行调试(只是将结果拍摄到 System.err),但我从未想过要这样使用它。
  • 我也是 :) 而且我还没有遇到过适用于集合或地图的一系列更改。
  • 修改条目时究竟发生了什么?我认为它改变了地图,并且 peek 中调用的动作应该是不干扰的。它对日志有好处,但如果我得到它,据我所知,它不应该以这种方式使用。
【解决方案2】:

如果您想修改现有地图而不是生成新地图(如您的示例中所示),则根本不需要使用流。使用Map.replaceAll:

items.replaceAll((k, v) -> renderTags(v));
return items;

如果您想保持原始地图不变,请查阅其他答案。

【讨论】:

  • 这里不是我需要的(新地图只是为了展示),但我不知道,所以我将它归档以备后用。谢谢!
  • 是的,这是我需要的解决方案。如果您不想要新地图,请使用此地图。
【解决方案3】:

你可以用Collectors.toMap()这样试试:

Map<Instant, String> getItems() {
    return items.entrySet().stream()
                .collect(Collectors.toMap(
                            Map.Entry::getKey,
                            entry -> renderTags(entry.getValue())
                         ));
}

顺便说一句,如果名称只是简单地说“get”,那么您通常不应该在其中转换它。人们期望 getter 简单且完全不昂贵。

【讨论】:

  • 是的,胜利者得到战利品。
【解决方案4】:

如果您想要 Map 作为结果:

Map<Instant, String> getItems() {
    return items.entrySet()
            .stream()
            .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    e -> renderTags(e.getValue())));
}

【讨论】:

  • 哦,好吧,你快了将近一分钟:/
  • 你们谁能告诉我为什么我会在Map.Entry::getKey 线上得到一个Cannot resolve method 'getKey' 吗?
  • 你确定你的Map导入真的是java.util.Map吗?
  • @DidierL 我刚刚检查以确保确实如此。
  • 对不起,我想通了。这是方法返回类型中的错字,以某种方式显示为我提到的错误。解决了这个问题,效果很好:)
猜你喜欢
  • 2019-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 2019-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多