使用Java8流api将函数列表应用于值

时间:2015-06-07 08:02:05

标签: java java-8 reduce

我想要一个单独的日志消息pojo LoggedExchange并对其应用一堆转换。转换是列表中的UnaryOperators:

List<ConditionalTransform> transforms = new ArrayList<>();

其中ConditionalTransform实现UnaryOperator<LoggedExchange>,我当前的解决方案是使用reduce,如下所示:

public LoggedExchange transform(LoggedExchange original) {
    return transforms.stream().reduce(original, (o, t) -> t.apply(o), (m1, m2) -> m2);
}

并行运行这个没有意义,因为没有办法组合两个消息((m1,m2) -> m2只是为了让编译器满意。)

有没有更好的方法来做到这一点(比如以某种方式组成所有ConditionalTranforms?)如果没有,那么combiner函数是否会抛出异常或其他东西,因为我无法支持并行执行?

JavaDoc指出,大多数这些操作应该可以与mapreduce进行,但我不知道如何操作。

2 个答案:

答案 0 :(得分:7)

这样的事情应该有效:

public LoggedExchange transform(LoggedExchange original) {
    return transforms.stream().reduce(UnaryOperator.identity(), (a, b) -> ((LoggedExchange o) -> b.apply(a.apply(o)))).apply(original);
}

这构造了一个UnaryOperator<LoggedExchange>,它依次应用transforms中的所有函数,然后使用输入值调用它。

或者,总是有简单的循环版本:

public LoggedExchange transform(LoggedExchange value) {
    for(UnaryOperator<LoggedExchange> transform : transforms)
        value = transform.apply(value);
    return value;
}

答案 1 :(得分:-2)

我认为你并没有真正减少任何东西。我认为你只是将字符串映射到另一个字符串中。

我会这样写:

trasforms
    .forEach(transformation -> transformation.apply(original));

请记得将原版宣布为最终版。