我需要对字符串应用regex列表,所以我想使用java8映射还原:
List<SimpleEntry<String, String>> list = new ArrayList<>();
list.add(new SimpleEntry<>("\\s*\\bper\\s+.*$", ""));
list.add(new SimpleEntry<>("\\s*\\bda\\s+.*$", ""));
list.add(new SimpleEntry<>("\\s*\\bcon\\s+.*$", ""));
String s = "Tavolo da cucina";
String reduced = list.stream()
.reduce(s, (v, entry) -> v.replaceAll(entry.getKey(), entry.getValue()) , (c, d) -> c);
实际上,这段代码可能不是很漂亮,但它能工作。我知道这不能并行化,对我来说也没问题。
现在我的问题是:是否有可能用Java8 (或更高版本)编写更优雅的东西?我的意思也是避免添加无用的组合器函数。
发布于 2018-06-01 09:59:33
受Oleksandr的评论和Holger的启发,我写了以下文章
String reduced = list.stream()
.map(entry->
(Function<String, String>) v -> v.replaceAll(entry.getKey(), entry.getValue()))
.reduce(Function.identity(), Function::andThen)
.apply(s);
这也将所有条目减少为函数组合。
发布于 2018-06-01 09:51:52
下面是另一种有趣的方法:将所有条目还原为函数组合,然后在原始输入中应用该组合函数:
String result = list.stream()
.map(entry ->
(Function<String, String>) text ->
text.replaceAll(entry.getKey(), entry.getValue()))
//following op also be written as .reduce(Function::compose) (see comment by Eugene)
.reduce((f1, f2) -> f1.andThen(f2)) //compose functions
.map(func -> func.apply(s)) //this basically runs all `replaceAll`
.get();
其结果是您期望的字符串。虽然这个函数组合并不直观,但它似乎符合这样的想法,即您的原始列表实际上是一种“转换逻辑”链。
https://stackoverflow.com/questions/50639966
复制相似问题