関数プログラミングの世界では、あるいは単に「パラメータに値をバインドする」機能の少ない用語で説明します。そこそのための組み込みの方法はませんが、それはあなた自身を書くことは簡単です:
public static <T,U,R> Function<U,R> bind(BiFunction<T,U,R> f, T t) {
return u -> f.apply(t, u);
}
次に、あなたはあなたのケースでそれを使用することができます。
FooBar<X,Y> instance=…;
BiFunction<FooBar<X,Y>,X,Y> barFunction=FooBar::bar;
Function<X,Y> myBarFunction=bind(barFunction, instance);
か、単に
// equivalent to myBarFunction=instance::bar
Function<X,Y> myBarFunction=bind(FooBar::bar, instance);
注意ユーティリティメソッドが、使用している機能インターフェイス(つまり、Function
およびBiFunction
)とタイトで、メソッド参照ではないことを確認してください。どのようなBiFunction
でも動作します。メソッドリファレンス、ラムダ式、または通常のクラスとして実装されます。しかし、具体的にはFunction
インスタンスが必要な場合にのみ役に立ち、1つのパラメータを取る任意の機能インタフェースでは役に立ちません。 Function
を::apply
を使用して別の単一引数関数型に変換できますが、bind(bifunc, value)::apply
を使用すると、インスタンスが必要な場所でx -> bifunc.apply(value, u)
以上の利点はありません。
BiFunction
をFunction
に変換する必要がある場合は、最初の引数を非常に頻繁にバインドして、ユーティリティメソッドを使用すると便利です。それ以外の場合は、実際のターゲットタイプが存在するコンテキストでラムダ式を使用してください。もちろん、他のインターフェースにも同様のメソッドを書くことができますが、このインターフェースは、特定のインターフェースで必要な場合にのみ便利です。
より多くのパラメータを取る関数に関しては、Java APIはそのような機能インタフェースを提供しないので、適切なインタフェースを自分で定義する必要があります。インタフェースに直接バインディング機能を提供するオプションを提供します。default
メソッド。あなたは
MyFunc4<U, W, X, Y, Z> func = …;
のような機能を持っている場合
interface MyFunc3<A,B,C,R> {
R apply(A a, B b, C c);
default BiFunction<B,C,R> bind(A a) {
return (b, c) -> apply(a, b, c);
}
}
interface MyFunc4<A,B,C,D,R> {
R apply(A a, B b, C c, D d);
default MyFunc3<B,C,D,R> bind(A a) {
return (b, c, d) -> apply(a, b, c, d);
}
}
そして、あなたは
MyFunc3<W, X, Y, Z> f3 = func.bind(u);
または
BiFunction<X, Y, Z> f2 = func.bind(u).bind(w);
いつものように華麗な説明、ホルガー。機能的なインターフェイスにインスタンスをバインドするためのデフォルトのメソッドを単に追加することは考慮されていませんでしたが、それは本当に便利なトリックです。 –