Roh*_*bhu 5 java functional-programming java-8 method-reference
如果我创建一个功能界面:
@FunctionalInterface
public class Consumer2<T1, T2> {
void accept(T1 t1, T2 t2);
default Consumer1<T2> curry(T1 t1) {
return (t2) -> accept(t1, t2);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我有一个班级:
public class MyClass {
public void printStrings(String a, String b) {
System.out.println(a + ": " + b);
}
}
MyClass myClass = new MyClass();
Run Code Online (Sandbox Code Playgroud)
现在,如果我想使用我的功能界面,我可以:
Consumer2<String, String> printString = myClass::printStrings;
printString.curry("hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
但我做不了类似的事情:
myClass::printStrings.curry("hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为Java无法知道myClass::printStrings
可以应用于功能接口Consumer2
.为此,我创建了一个实用程序类:
public class F {
public static <T1, T2> Consumer2<T1, T2> c2(Consumer2<T1, T2> fn) {
return fn;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以:
F.c2(myClass::printStrings).curry("hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
甚至,这将工作:
((Consumer2<String, String>)myClass::printStrings).curry("hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
只要有一些方法让Java 8在这种情况下理解该功能类型.所以,问题是,最好的方法是什么,同时可能避免使用样板?
您涉及F.c2
方法的解决方案很有趣,但您的示例太人为了。如果你问,如何更好地编写这段代码
F.c2(myClass::printStrings).curry("hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
那么我肯定会建议你这样写:
myClass.printStrings("hello", "world");
Run Code Online (Sandbox Code Playgroud)
如果你想问如何将预定义参数绑定到方法引用,我建议你使用 lambda 函数:
Consumer1<String> fn = str -> myClass.printStrings("hello", str);
fn.accept("world");
Run Code Online (Sandbox Code Playgroud)
您可能想考虑在编译时未知您的函数的情况。在这种情况下,它要么从另一个方法返回,要么作为方法参数传递给当前方法,或者存储在变量/字段中。在所有这些情况下,它已经是功能接口,您可以curry
直接使用:
Consumer2<String, String> getConsumer2() { return myClass::printStrings; }
getConsumer2().curry("hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
因此,总的来说,我没有看到这里的问题。如果您仍然认为对方法引用应用柯里化很有用,我会curry
在接口中创建一个静态方法(尽管我猜,它实际上是“绑定”,而不是“柯里化”)Consumer1
:
static <T1, T2> Consumer1<T2> curry(Consumer2<T1, T2> c2, T1 t1) {
return c2.curry(t1);
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
Consumer1.curry(myClass::printStrings, "hello").accept("world");
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
146 次 |
最近记录: |