Java 如何链接双功能?

Java 如何链接双功能?,java,functional-programming,java-8,Java,Functional Programming,Java 8,我想链接双函数,就像下面代码示例中的方法chainwant一样 双函数将函数作为和的参数。是否有可能以某种方式链双功能 由于这个原因,这里的代码无法编译,我无法将双函数转换为函数 import java.util.function.BiFunction; import java.util.function.Function; import org.openqa.selenium.remote.RemoteWebDriver; public class Wf { BiFunction

我想链接双函数,就像下面代码示例中的方法
chainwant
一样

双函数将函数作为和的参数。是否有可能以某种方式链双功能

由于这个原因,这里的代码无法编译,我无法将双函数转换为函数

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, WfParams, RemoteWebDriver> wait = this::wait;

    BiFunction<RemoteWebDriver, WfParams, RemoteWebDriver> chainNow = init
            .andThen(d -> {
                System.out.println("--------------");
                return null;
            });

    BiFunction<RemoteWebDriver, WfParams, 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);
    }
}
import java.util.function.BiFunction;
导入java.util.function.function;
导入org.openqa.selenium.remote.RemoteWebDriver;
公共类Wf{
BiFunction init=this::init;
双功能等待=this::wait;
双功能chainNow=init
.然后(d->{
System.out.println(“--------------”;
返回null;
});
双功能链=初始化
.然后((双功能)等待);
公共RemoteWebDriver初始化(RemoteWebDriver d,WfParams-params){
System.out.println(“init(d,params)”;
返回d;
}
公共RemoteWebDriver等待(RemoteWebDriver d,WfParams params){
System.out.println(“Wf.wait(d,params)”;
返回d;
}
公共静态void main(字符串[]args)引发异常{
新的Wf().start();
}
私有void start(){
chainNow.apply(null,null);
}
}

调用
wait
时,wfparms应该从哪里来?如果要对所有函数调用重用相同的WfParams,只需将WfParams作为类成员变量,而不是将其传递给每个函数

class Wf {
    private final WfParams params;

    public Wf(WfParams params) {
        this.params = params;
    }

    UnaryOperator<RemoteWebDriver> init = this::init;
    UnaryOperator<RemoteWebDriver> wait = this::wait;

    Function<RemoteWebDriver,RemoteWebDriver> chain = init.andThen(wait);

    RemoteWebDriver init(RemoteWebDriver d) {
        // can use WfParams here
        return d;
    }

    RemoteWebDriver wait(RemoteWebDriver d) {
        // can use WfParams here            
        return d;
    }

    private void start() {
        chain.apply(null);
    }

    public static void main(String[] args) {
        new Wf(new WfParams()).start();
    }   
}
Wf类{
私有最终wfparms参数;
公共Wf(WfParams参数){
this.params=params;
}
UnaryOperator init=this::init;
UnaryOperator wait=此::wait;
函数链=初始和第二(等待);
RemoteWebDriver初始化(RemoteWebDriver d){
//可以在这里使用WfParams
返回d;
}
RemoteWebDriver等待(RemoteWebDriver d){
//可以在这里使用WfParams
返回d;
}
私有void start(){
链。应用(空);
}
公共静态void main(字符串[]args){
新Wf(新WfParams()).start();
}   
}

有没有一个特别的原因,你想使用函数链接这样?为什么不直接调用
init(…);等等(…)start()

将一个
函数链接到另一个
函数自然有效,因为第一个函数的返回值作为参数传递给下一个函数,而该函数的返回值作为参数传递给后续函数,依此类推。对于
BiFunction
来说,这并不自然,因为它们有两个参数。第一个参数是前一个函数的返回值,但第二个参数是什么?它还解释了为什么
BiFunction
允许使用
链接,然后
链接到一个
函数而不是另一个
BiFunction

然而,这表明,如果有某种方式为第二个参数提供值,则可以将一个
双函数链接到另一个
。这可以通过创建一个助手函数来实现,该函数将第二个参数的值存储在局部变量中。然后,通过从环境中捕获局部变量并将其用作第二个参数,可以将
双函数
转换为
函数

下面是它的样子

BiFunction<RemoteWebDriver, WfParams, 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);

它从词法环境中捕获
参数
。这给出了一个lambda表达式,它接受一个参数并返回一个值,因此它现在是一个
函数
,它包装了
等待
,它是一个
双函数
。这是部分应用或咖喱的示例。最后,我们使用
apply()
调用生成的
BiFunction
,传递原始参数。

我做了类似的事情-创建了我的自定义BiFunction。 其想法是:

  • 返回类型与第二个参数相同

  • 第一个参数在内部传递给链式双函数

    public interface BiFunctionCustom<T, U> extends BiFunction<T,U,U> {
    
      default BiFunctionCustom<T, U> andThen(BiFunctionCustom<T, U> after) {
          Objects.requireNonNull(after);
          return (T t, U u) -> after.apply(t, apply(t, u));
      }
    }
    
    公共接口双功能自定义扩展双功能{
    默认的双功能自定义和(双功能自定义之后){
    对象。requirennull(之后);
    return(T,U)->after.apply(T,apply(T,U));
    }
    }
    

  • 我不明白你怎么能从一开始就把双功能链起来;双函数的结果是一个参数,您打算如何将它链接到另一个参数中?
    public interface BiFunctionCustom<T, U> extends BiFunction<T,U,U> {
    
      default BiFunctionCustom<T, U> andThen(BiFunctionCustom<T, U> after) {
          Objects.requireNonNull(after);
          return (T t, U u) -> after.apply(t, apply(t, u));
      }
    }