Java 8:BiFunction在使用andThen()和apply()方法时如何工作

时间:2019-06-03 05:18:06

标签: java builder functional-interface

当前BiFunction接口有两种方法andThen()apply()。我在网络上找到了不同的示例,但下面的示例是我无法弄清楚的-“这些方法的链接如何工作”

示例1:

BiFunction<String, String,String> bi = (x, y) -> {
                    return x + y;
                    };

Function<String,String> f = x-> x+" spinner";

System.out.println(bi.andThen(f).apply("hello", " world"));

在阅读了链接“ Default andThen() method in BiFunction interface”之后,我在下面几行

  

假设我们有两个函数f和g,函数f执行一些逻辑,函数g执行其他类型的逻辑,因此当您编写f.andThen(g)时,实质上意味着g(f(x)),即我们首先应用作为参数f(x)给出的函数,然后将函数g应用于结果。

并得出结论:bi.apply("hello", " world"))首先发生,然后result是 传递给bi.andThen(f(result)),这将产生最终输出hello world spinner

我在某种程度上了解,但并不完全满意。我不得不问这个问题,因为过去我使用过构建器模式,它类似于下面的内容,

BankAccount account = new BankAccount.Builder("bank_account")
                                 .withOwner("account_owner")
                                 .atBranch("branch_name")
                                 .openingBalance(balance)
                                 .build();

在这里,方法调用按顺序进行,首先初始化Builder(静态)类,然后withOwner分配所有者名称并返回builder,然后分配分支名称并返回builder, 给出下一个期初余额并返回构建器,最后构建将返回BankAccount实例。请参阅BankAccount类。

public class BankAccount {

    public static class Builder {

        private long accountNumber; 
        private String owner;
        private String branch;
        private double balance;

        public Builder(long accountNumber) {
            this.accountNumber = accountNumber;
        }

        public Builder withOwner(String owner){
            this.owner = owner;
            return this; 
        }

        public Builder atBranch(String branch){
            this.branch = branch;
            return this;
        }

        public Builder openingBalance(double balance){
            this.balance = balance;
            return this;
        }



        public BankAccount build(){
            //Here we create the actual bank account object, which is always in a fully initialised state when it's returned.

            BankAccount account = new BankAccount();  //Since the builder is in the BankAccount class, we can invoke its private constructor.
            account.accountNumber = this.accountNumber;
            account.owner = this.owner;
            account.branch = this.branch;
            account.balance = this.balance;

            return account;
        }
    }

}

如您所见,方法是按顺序调用的,方法-withOwneratBranchopeningBalance的输出是链中的Builder实例。对我来说,这称为方法链,因为每个方法的输出顺序都将在以后使用,这非常清楚。但是,我的问题是-上面示例1 (BiFunction and its methods chaining)的方法链接如何在内部内部工作。

3 个答案:

答案 0 :(得分:0)

您可以查看默认实现:

default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
    Objects.requireNonNull(after);
    return (T t, U u) -> after.apply(apply(t, u));
}

如您所见,首先他们调用apply的{​​{1}}方法(即,他们求值BiFunction),然后将该方法的结果传递到{{1} }的apply(t, u)方法(Function)。

我不确定您为什么感到apply没有按顺序调用方法。毕竟after.apply(...)创建了一个andThen,它首先调用bi.andThen(f)的{​​{1}}方法,然后调用BiFunction的{​​{1}}方法(就像名称bi表示)。

答案 1 :(得分:0)

这是简单的函数组成,这意味着如果要给结果函数起一个名字:

BiFunction<String, String, String> composed = bi.andThen(f);

那么一个简单的定义是:

composed(x,y) = f(bi(x,y))

因此,BiFunction.andThen返回一个BiFunction,它将应用当前(bi)函数的逻辑来计算结果,然后将该结果传递给另一个函数(f),并应用该函数返回最终输出的逻辑。

答案 2 :(得分:0)

andThen方法与Builder模式在以下方面有所不同:

andThen返回一个新函数,该函数由其他两个函数组成,而构建器的每个方法都返回自身,只是允许链接方法调用,从而使代码更紧凑,但是您也可以写:

BankAccount.Builder builder = new BankAccount.Builder("bank_account");
builder.withOwner("account_owner");
builder.atBranch("branch_name");
builder.openingBalance(balance);
BankAccount account = builder.build();

此外,使用andThen方法,所有内容都是不可变的,而生成器本质上是可变的(尽管生成的对象本身通常是不可变的)。