在功能上撰写java Function
和Consumer
的最佳方法是什么?
例如,给定一些Function<Object, String> f
和一些Consumer<String> c
,然后执行f.andThen(c)
会感觉很自然,但这不是接口的工作方式。
我看到的两个选项是将Consumer<String> c
替换为Function<String, Void> c
或将Consumer<String> c
更改为BiConsumer<Function<Object, String>, String> c
并执行
accept(Function<Object, String> f, Object o) {
String thing = f.apply(o);
//do something with thing
}
其中一个比另一个好吗?还有更好的方法吗?
答案 0 :(得分:10)
这是你想要做的吗?
Consumer<Object> composed = o -> c.accept(f.apply(o));
如果你发现自己经常遇到这个问题,你可以制定一个静态方法来做到这一点(但真的值得吗?):
static<T,R> Consumer<T> applyAndAccept(Function<? super T,? extends R> f, Consumer<R> c){
return t -> c.accept(f.apply(t));
}
答案 1 :(得分:1)
您可以在自己的代码中复制java.util.function.Function接口。将其命名为ConsumableFunction并更改所有默认方法参数类型,并将值从Function返回到ConsumableFunction。然后添加以下默认函数:
default Consumer<T> atLast(Consumer<R> consumer) {
Objects.requireNonNull(consumer);
return (T t) -> consumer.accept(apply(t));
}
现在让所有的功能实现代替实现ConsumableFunction。然后你可以编写这样的代码:
Consumer<A> consumerForA = functionFromAToB
.andThen(functionFromBToC)
.andThen(functionFromCToD)
.atLast(consumerForD);
答案 2 :(得分:0)
使用map
和forEach
public void test() {
Function<Object, String> f = (Object t) -> t.toString();
Consumer<String> c = (String t) -> {
System.out.println(t);
};
List<Object> data = new ArrayList<>();
data.stream().map(f).forEach(c);
}