用无用的组合器减少java8

时间:2018-06-01 09:13:39

标签: java java-8 java-stream reduce

我需要将一个正则表达式列表应用到字符串中,所以我想用java8 map reduce:

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(或更高版本)是否有机会写出更优雅的东西?我的意思是也避免添加无用的组合器功能。

2 个答案:

答案 0 :(得分:2)

受到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);

这也会减少函数组合的所有条目。

答案 1 :(得分:1)

这是另一种有趣的方法:将所有条目减少为函数组合,然后将该组合函数应用于原始输入:

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();

这是您期望的字符串。虽然这个功能组合不直观,但它似乎符合你的原始列表实际上是一种转换逻辑&#34;链