为什么有必要明确说一个lambda是Consumer使用andThen方法? [英] Why is necessary to explicitly say a lambda is Consumer to use andThen method?

查看:253
本文介绍了为什么有必要明确说一个lambda是Consumer使用andThen方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试使用两个void方法的函数组合时,我遇到了一个奇怪的(对我来说)行为。我写了一个简单的例子来说明问题:

I've faced a strange(for me) behavior when I was trying to use function composition with two void methods. I've written a simple example to illustrate the problem :

public class Startup {

    public static void main(String[] args) {

        List<Foo> foos = new ArrayList<>();

        // 1) Does not compile
        foos.forEach(Startup::doSomething1.andThen(Startup::doSomething2));

        Consumer<Foo> doSomething1 = Startup::doSomething1;
        Consumer<Foo> doSomething2 = Startup::doSomething2;

        // 2) Works as expected 
        foos.forEach(doSomething1.andThen(doSomething2));

    }

    public static void doSomething1(Foo foo) {

    }

    public static void doSomething2(Foo foo) {

    }

    public static class Foo {

    }

}

当我尝试编译第一个解决方案时,它会说'')'预期'然后再拨打电话。

When I try to compile the first solution it says "')' expected" before andThen call.

当我明确说这是消费者时,代码被编译并且按预期工作。

When I explicitly say this are Consumers the code is compiled and it works as expected.

任何人都可以解释为什么会发生这种情况,是否有另一种方法用Java 8进行void方法的函数组合?

Can anyone explain to my why this is happening and is there another way of doing function composition of void methods with Java 8?

推荐答案

这必须使用Java推断,转换和检测lambdas中的类型的方式。正如上面的评论所述,转换为 Consumer< Foo> 尚未发生,这意味着编译器不知道这是消费者以便您可以在之后链接 andThen()

This has to do with the way Java inferes, converts and detects types in lambdas. As mentioned in a comment above, the conversion to Consumer<Foo> has not taken place yet meaning that the compiler does not know that this is a Consumer so that you can chain an andThen() afterwards.

明确地将其转换为a 消费者并正确使用括号可以达到预期的效果:

Explicitly casting this to a Consumer and using parentheses properly will let you achieve the desired effect:

List<Foo> foos = new ArrayList<>();
foos.forEach(((Consumer<Foo>) Null::doSomething).andThen(Null::doSomething2));

我想如果你摆弄它,你可以使用类型证人达到相同的行为,但我是不是100%肯定他们是否能达到预期的效果。

I guess if you fiddle around with it, you can achieve the same behavior using type witnesses but I am not 100% sure whether they can achieve the desired result.

我第一次注意到这是使用可能表现出相同行为的链式比较器。对此进行在线搜索将向您显示有关其工作原理的更复杂细节。

First time I noticed this was using chained comparators which may exhibit the same behavior. Doing an online search about that will show you some more intricate details regarding how this works.

这篇关于为什么有必要明确说一个lambda是Consumer使用andThen方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆