编写Java函数和使用者

时间:2015-09-18 07:28:12

标签: java functional-programming java-8 function-composition

在功能上撰写java FunctionConsumer的最佳方法是什么? 例如,给定一些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
}

其中一个比另一个好吗?还有更好的方法吗?

3 个答案:

答案 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)

使用mapforEach

完成了吗?
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);
}