使用java 8流将字符串替换为哈希图值
Posted
技术标签:
【中文标题】使用java 8流将字符串替换为哈希图值【英文标题】:Replace String With hashmap value using java 8 stream 【发布时间】:2016-07-10 09:49:28 【问题描述】:我有String
和HashMap
如下代码:
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 中有很多元素怎么办? @ChheaVanrin0
指的是List
,而不是Map
。 forEach()
将处理尽可能多的地图条目。
对不起,我没看清楚 :) 。但这似乎不那么合乎逻辑。我只想使用完全 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流将字符串替换为哈希图值的主要内容,如果未能解决你的问题,请参考以下文章
[Java]_[初级]_[使用正则高效替换字符串的多个占位符为多个值]
[Java]_[初级]_[使用正则高效替换字符串的多个占位符为多个值]