我想链接BiFunctions,就像在下面的代码示例中的方法chainWanted中一样.
BiFunction将Function作为AndThen的参数.有可能以某种方式链接BiFunctions?
这里的代码因为这个而无法编译,我无法将BiFunction转换为Function.
import java.util.function.BiFunction; import java.util.function.Function; import org.openqa.selenium.remote.RemoteWebDriver; public class Wf { BiFunction<RemoteWebDriver,WfParams,RemoteWebDriver> init = this::init; BiFunction<RemoteWebDriver,RemoteWebDriver> wait = this::wait; BiFunction<RemoteWebDriver,RemoteWebDriver> chainNow = init .andThen(d -> { System.out.println("--------------"); return null; }); BiFunction<RemoteWebDriver,RemoteWebDriver> chainWanted = init .andThen((BiFunction) wait); public RemoteWebDriver init(RemoteWebDriver d,WfParams params) { System.out.println("init(d,params)"); return d; } public RemoteWebDriver wait(RemoteWebDriver d,WfParams params) { System.out.println("Wf.wait(d,params)"); return d; } public static void main(String[] args) throws Exception { new Wf().start(); } private void start() { chainNow.apply(null,null); } }
解决方法
将一个函数链接到另一个函数会自然地起作用,因为第一个函数的返回值作为参数传递给下一个函数,并且该函数的返回值作为参数传递给后续函数,依此类推.这对BiFunction不起作用,因为它们有两个参数.第一个参数是前一个函数的返回值,但第二个参数是什么?它还解释了为什么BiFunction允许使用andThen链接到函数而不是另一个BiFunction.
然而,这表明如果有某种方式为第二个参数提供值,则可以将一个BiFunction链接到另一个BiFunction.这可以通过创建一个辅助函数来完成,该函数将第二个参数的值存储在局部变量中.然后,可以通过从环境中捕获该局部变量并将其用作第二个参数,将BiFunction转换为Function.
这就是看起来的样子.
BiFunction<RemoteWebDriver,RemoteWebDriver> chainWanted = this::chainHelper; RemoteWebDriver chainHelper(RemoteWebDriver driver,WfParams params) { return init.andThen(rwd -> wait.apply(rwd,params)) .apply(driver,params); } // ... chainWanted.apply(driver,params);
chainHelper方法保存params参数以便以后捕获.我们调用init.andThen()来进行链接.但这需要一个函数,而等待是一个BiFunction.而不是使用方法引用this :: wait我们使用lambda表达式
rwd -> wait.apply(rwd,params)
它从词汇环境中捕获了参数.这给出了一个lambda表达式,它接受一个参数并返回一个值,因此它现在是一个包装等待的函数,这是一个BiFunction.这是部分应用或currying的一个例子.最后,我们使用apply()调用生成的BiFunction,传递原始参数.