Java 8:BiFunction 在使用 andThen() 和 apply() 方法时如何工作
Java 8: How BiFunction works while using andThen() and apply() methods
目前BiFunction
接口有两个方法andThen()
和apply()
。我在网上找到了不同的例子,但下面的例子是我无法理解的 - 'How the chaining of these methods works'
示例 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"));
阅读完 link '' 后,我采用了以下行
Assume we had two functions f and g , function f doing some logic and function g doing some other type of logic so when you compose f.andThen(g) that essentially means g(f(x)) i.e. we first apply the function given as argument f(x) and then apply the function g to the result.
并得出结论,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
(静态)class,然后 withOwner
分配所有者名称和 returns 构建器,然后分配分支名称和 returns 构建器,
下一个初始余额和 returns 构建器,最后构建将 return BankAccount
实例。请参阅 BankAccount
class.
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;
}
}
}
如您所见,方法是按顺序调用的,方法的输出 -withOwner
、atBranch
、openingBalance
是链中的 Builder
个实例。对我来说,这被称为方法链,因为每个方法的输出按顺序供以后使用,这一点非常清楚。但是,我的问题是 - 上述示例 1 (BiFunction and its methods chaining)
的方法链接如何在内部 .
工作
可以看看默认实现:
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));
}
如您所见,首先他们调用 BiFunction
的 apply
方法(即他们评估 apply(t, u)
),然后该方法的结果传递给 Function
的 apply
方法 (after.apply(...)
).
我不确定为什么您觉得 andThen
没有按顺序调用这些方法。毕竟 bi.andThen(f)
创建了一个 BiFunction
,它首先调用 bi
的 apply
方法,然后调用 f
的 apply
方法(就像名称 andThen
表示)。
很简单函数组合,意思是如果我们要给结果函数一个名字:
BiFunction<String, String, String> composed = bi.andThen(f);
那么一个简单的定义就是:
composed(x,y) = f(bi(x,y))
所以 BiFunction.andThen
returns 一个 BiFunction
将应用当前 (bi
) 函数的逻辑来计算结果,然后传递给另一个函数 (f
), 将其逻辑应用于 return 最终输出。
andThen
方法在几个方面不同于 Builder
模式:
andThen
returns 一个由另外两个函数组成的新函数,而构建器 returns 本身的每个方法,只是为了允许方法调用的链接,因此使代码更紧凑,但你也可以这样写:
BankAccount.Builder builder = new BankAccount.Builder("bank_account");
builder.withOwner("account_owner");
builder.atBranch("branch_name");
builder.openingBalance(balance);
BankAccount account = builder.build();
此外,使用 andThen
方法,一切都是不可变的,而构建器本质上是可变的(尽管构建的对象本身通常是不可变的)。
目前BiFunction
接口有两个方法andThen()
和apply()
。我在网上找到了不同的例子,但下面的例子是我无法理解的 - 'How the chaining of these methods works'
示例 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"));
阅读完 link '
Assume we had two functions f and g , function f doing some logic and function g doing some other type of logic so when you compose f.andThen(g) that essentially means g(f(x)) i.e. we first apply the function given as argument f(x) and then apply the function g to the result.
并得出结论,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
(静态)class,然后 withOwner
分配所有者名称和 returns 构建器,然后分配分支名称和 returns 构建器,
下一个初始余额和 returns 构建器,最后构建将 return BankAccount
实例。请参阅 BankAccount
class.
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;
}
}
}
如您所见,方法是按顺序调用的,方法的输出 -withOwner
、atBranch
、openingBalance
是链中的 Builder
个实例。对我来说,这被称为方法链,因为每个方法的输出按顺序供以后使用,这一点非常清楚。但是,我的问题是 - 上述示例 1 (BiFunction and its methods chaining)
的方法链接如何在内部 .
可以看看默认实现:
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));
}
如您所见,首先他们调用 BiFunction
的 apply
方法(即他们评估 apply(t, u)
),然后该方法的结果传递给 Function
的 apply
方法 (after.apply(...)
).
我不确定为什么您觉得 andThen
没有按顺序调用这些方法。毕竟 bi.andThen(f)
创建了一个 BiFunction
,它首先调用 bi
的 apply
方法,然后调用 f
的 apply
方法(就像名称 andThen
表示)。
很简单函数组合,意思是如果我们要给结果函数一个名字:
BiFunction<String, String, String> composed = bi.andThen(f);
那么一个简单的定义就是:
composed(x,y) = f(bi(x,y))
所以 BiFunction.andThen
returns 一个 BiFunction
将应用当前 (bi
) 函数的逻辑来计算结果,然后传递给另一个函数 (f
), 将其逻辑应用于 return 最终输出。
andThen
方法在几个方面不同于 Builder
模式:
andThen
returns 一个由另外两个函数组成的新函数,而构建器 returns 本身的每个方法,只是为了允许方法调用的链接,因此使代码更紧凑,但你也可以这样写:
BankAccount.Builder builder = new BankAccount.Builder("bank_account");
builder.withOwner("account_owner");
builder.atBranch("branch_name");
builder.openingBalance(balance);
BankAccount account = builder.build();
此外,使用 andThen
方法,一切都是不可变的,而构建器本质上是可变的(尽管构建的对象本身通常是不可变的)。