使用java 8流将字符串替换为哈希图值

Posted

技术标签:

【中文标题】使用java 8流将字符串替换为哈希图值【英文标题】:Replace String With hashmap value using java 8 stream 【发布时间】:2016-07-10 09:49:28 【问题描述】:

我有StringHashMap 如下代码:

Map<String, String> map = new HashMap<>();
    map.put("ABC", "123");
    String test = "helloABC";
    map.forEach((key, value) -> 
        test = test.replaceAll(key, value);
    );

我尝试用HashMap 值替换字符串,但这不起作用,因为test 是最终的,不能在forEach 的正文中重新分配。

那么有没有使用 Java 8 Stream API 将 String 替换为 HashMap 的解决方案?

【问题讨论】:

forEach() 未同步。您的代码无法编译,因为您不能从 lambda 表达式内部对 message 产生副作用。即使你可以,你得到的只是message 包含test 上最后一个地图条目的最后一个替换。这可能不是你想要的。还因为“最后一个地图条目”对于HashMap 是不确定的。 好的,谢谢,我知道了。但是我应该怎么做才能获得已经替换的所有测试内容? 【参考方案1】:

因为这不能只使用forEach()message 必须是有效的最终),解决方法可能是创建一个最终容器(例如List),它存储一个被重写的String

final List<String> msg = Arrays.asList("helloABC");
map.forEach((key, value) -> msg.set(0, msg.get(0).replace(key, value)));
String test = msg.get(0);

请注意,我将 replaceAll() 更改为 replace() 因为前者适用于正则表达式,但从您的代码来看,您似乎需要用字符串本身替换(不用担心,尽管名称令人困惑,它也替换了 all 次)。

如果你想要确切的 Stream API,你可以使用reduce() 操作:

String test = map.entrySet()
                 .stream()
                 .reduce("helloABC", 
                         (s, e) -> s.replace(e.getKey(), e.getValue()), 
                         (s1, s2) -> null);

但请注意,这种减少只能在串行(非并行)流中正常工作,其中永远不会调用组合函数(因此可能是任何函数)。

【讨论】:

我已经试过了,但它看起来很棘手。如果我们在 Map 中有很多元素怎么办? @ChheaVanrin 0 指的是List,而不是MapforEach() 将处理尽可能多的地图条目。 对不起,我没看清楚 :) 。但这似乎不那么合乎逻辑。我只想使用完全 java 8 流。无论如何谢谢:)【参考方案2】:

这类问题不太适合 Streams API。 Streams 的当前化身主要针对可以并行的任务。将来可能会添加对此类操作的支持(请参阅https://bugs.openjdk.java.net/browse/JDK-8133680)。

您可能会发现一种有趣的基于流的方法是减少函数而不是字符串:

Function<String, String> combined = map.entrySet().stream()
    .reduce(
        Function.identity(),
        (f, e) -> s -> f.apply(s).replaceAll(e.getKey(), e.getValue()),
        Function::andThen
    );

String result = combined.apply(test);

【讨论】:

似乎没有机会在 Java-9 中看到foldLeft。不幸的是。 @TagirValeev 几个月前我看到了你在 core-lib 邮件列表上的努力。感谢您的尝试。

以上是关于使用java 8流将字符串替换为哈希图值的主要内容,如果未能解决你的问题,请参考以下文章

替换hashmap java中的重复值字符串

[Java]_[初级]_[使用正则高效替换字符串的多个占位符为多个值]

[Java]_[初级]_[使用正则高效替换字符串的多个占位符为多个值]

如何使用 REGEXP_REPLACE 检查字符串中是不是存在值“已关闭”并替换

如何在java中用\替换字符串中的“(双引号)”

如何使用流将列表转换为带有索引的地图 - Java 8?