将函数列表应用于具有 Java8 流 api 的值
Applying a list of functions to a value with Java8 stream api
我想要获取单个日志消息 pojo LoggedExchange
并对其应用一系列转换。转换是列表中的一元运算符:
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 指出这些操作中的大多数应该可以用 map
和 reduce
来处理,但我不知道如何处理。
像这样的东西应该可以工作:
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;
}
我不认为你真的在减少任何东西。我认为您只是将一个字符串映射到另一个字符串中。
我会这样写:
trasforms
.forEach(transformation -> transformation.apply(original));
并记得将原件声明为最终版本。
我想要获取单个日志消息 pojo LoggedExchange
并对其应用一系列转换。转换是列表中的一元运算符:
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 指出这些操作中的大多数应该可以用 map
和 reduce
来处理,但我不知道如何处理。
像这样的东西应该可以工作:
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;
}
我不认为你真的在减少任何东西。我认为您只是将一个字符串映射到另一个字符串中。
我会这样写:
trasforms
.forEach(transformation -> transformation.apply(original));
并记得将原件声明为最终版本。