use*_*540 9 java lambda java-8
给出以下变量
templateText = "Hi ${name}";
variables.put("name", "Joe");
Run Code Online (Sandbox Code Playgroud)
我想使用以下代码(不起作用)将值占位符$ {name}替换为值"Joe"
variables.keySet().forEach(k -> templateText.replaceAll("\\${\\{"+ k +"\\}" variables.get(k)));
Run Code Online (Sandbox Code Playgroud)
但是,如果我采用"旧式"的方式,一切都很完美:
for (Entry<String, String> entry : variables.entrySet()){
String regex = "\\$\\{" + entry.getKey() + "\\}";
templateText = templateText.replaceAll(regex, entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)
当然我在这里遗漏了一些东西:)
Did*_*r L 16
实现这一点的正确方法在Java 8中没有改变,它基于appendReplacement()/ appendTail():
Pattern variablePattern = Pattern.compile("\\$\\{(.+?)\\}");
Matcher matcher = variablePattern.matcher(templateText);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(result, variables.get(matcher.group(1)));
}
matcher.appendTail(result);
System.out.println(result);
Run Code Online (Sandbox Code Playgroud)
请注意,正如drrob在评论中所提到的,替换字符串appendReplacement()可以包含使用$符号的组引用,并使用转义\.如果不需要,或者替换String可能包含这些字符,则应使用它们进行转义Matcher.quoteReplacement().
如果你想要一个更加Java-8风格的版本,你可以将搜索和替换样板代码提取到一个需要替换的通用方法中Function:
private static StringBuffer replaceAll(String templateText, Pattern pattern,
Function<Matcher, String> replacer) {
Matcher matcher = pattern.matcher(templateText);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(result, replacer.apply(matcher));
}
matcher.appendTail(result);
return result;
}
Run Code Online (Sandbox Code Playgroud)
并用它作为
Pattern variablePattern = Pattern.compile("\\$\\{(.+?)\\}");
StringBuffer result = replaceAll(templateText, variablePattern,
m -> variables.get(m.group(1)));
Run Code Online (Sandbox Code Playgroud)
请注意,使用Patternas参数(而不是a String)允许将其存储为常量,而不是每次都重新编译它.
同样的评论适用的有关上述$及\-你可能要执行quoteReplacement()里面replaceAll()的方法,如果你不想让你的replacer函数来处理它.
你也可以使用Stream.reduce(identity,accumulator,combiner).
identity是减少函数的初始值accumulator.
accumulator如果流是顺序的,则减少identity到result,即identity下一次减少.
永远不会在顺序流中调用此函数.它计算下一个identity从identity&result在并行流.
BinaryOperator<String> combinerNeverBeCalledInSequentiallyStream=(identity,t) -> {
throw new IllegalStateException("Can't be used in parallel stream");
};
String result = variables.entrySet().stream()
.reduce(templateText
, (it, var) -> it.replaceAll(format("\\$\\{%s\\}", var.getKey())
, var.getValue())
, combinerNeverBeCalledInSequentiallyStream);
Run Code Online (Sandbox Code Playgroud)