使用Java8流api将函数列表应用于值
我想要一个单独的日志消息pojo使用Java8流api将函数列表应用于值,java,java-8,reduce,Java,Java 8,Reduce,我想要一个单独的日志消息pojoLoggedExchange,并对其应用一系列转换。转换是列表中的一元运算符: List<ConditionalTransform> transforms = new ArrayList<>(); 并行运行此命令是没有意义的,因为没有办法将两条消息组合在一起(m1,m2)->m2的存在只是为了让编译器满意) 有没有更好的方法来实现这一点(比如以某种方式组合所有的条件tranforms?),如果没有,那么组合器函数是否应该抛出异常或其他原因
LoggedExchange
,并对其应用一系列转换。转换是列表中的一元运算符:
List<ConditionalTransform> transforms = new ArrayList<>();
并行运行此命令是没有意义的,因为没有办法将两条消息组合在一起(m1,m2)->m2的存在只是为了让编译器满意)
有没有更好的方法来实现这一点(比如以某种方式组合所有的条件tranforms
?),如果没有,那么组合器
函数是否应该抛出异常或其他原因,因为我无法支持并行执行
声明说,这些操作中的大多数应该可以使用
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
,它依次应用变换中的所有函数,然后用输入值调用它
或者,总是有简单的循环版本:
public LoggedExchange transform(LoggedExchange value) {
for(UnaryOperator<LoggedExchange> transform : transforms)
value = transform.apply(value);
return value;
}
公共LoggedExchange转换(LoggedExchange值){
for(一元运算符变换:变换)
value=transform.apply(值);
返回值;
}
我不认为你真的在减少任何东西。我认为您只是将一个字符串映射到另一个字符串中
我将写下:
trasforms
.forEach(transformation -> transformation.apply(original));
请记住将“原始”声明为“最终”。是否需要使用流?不,我只是想使用流:)如果您知道这不合适,您永远不应该提供一个默默地执行某些操作的组合器。如果你真的没有选择的话,就提供一个抛出合并器。第一个例子没有为我编译。最后一个.apply
不存在,并且reduce
操作不合法,IDE说lambda转换的目标类型必须是接口
@vertti-Fixed。我没有注意到带有一个参数的reduce
返回了一个可选的
(这在流没有元素的情况下是有意义的)。好了,现在最后一个.apply可以工作了,但是(LoggedExchange o)->b.apply(a.apply(o))
部分仍然抱怨“lambda转换的目标类型必须是一个接口”。@vertti(显然,该示例没有运行,因为它没有main方法,但它可以编译)注意:如果transforms
是集合
,则可以使用.reduce(Function.identity(),Function::and then)
。(如果它是一个集合
,并且您这样做了,那么类型推断失败,即使UnaryOperator
扩展了函数
),这只不过是一个代价高昂的noop。为什么呢?我错过了什么吗?因为您正在将原始值转换为其他值,并且对转换结果不做任何操作。
trasforms
.forEach(transformation -> transformation.apply(original));