gpt4 book ai didi

java - 如何在 Java 8 中直接使用函数作为函数类型

转载 作者:搜寻专家 更新时间:2023-10-31 19:54:01 24 4
gpt4 key购买 nike

如果我创建一个函数式接口(interface):

@FunctionalInterface
public class Consumer2<T1, T2> {
void accept(T1 t1, T2 t2);

default Consumer1<T2> curry(T1 t1) {
return (t2) -> accept(t1, t2);
}
}

现在,如果我有一个类:

public class MyClass {
public void printStrings(String a, String b) {
System.out.println(a + ": " + b);
}
}

MyClass myClass = new MyClass();

现在,如果我想使用我的功能接口(interface),我可以:

Consumer2<String, String> printString = myClass::printStrings;
printString.curry("hello").accept("world");

但我不能做类似的事情:

myClass::printStrings.curry("hello").accept("world");

这是有道理的,因为 Java 无法知道 myClass::printStrings 可以应用于功能接口(interface) Consumer2。为此,我创建了一个实用程序类:

public class F {
public static <T1, T2> Consumer2<T1, T2> c2(Consumer2<T1, T2> fn) {
return fn;
}
}

然后我可以:

F.c2(myClass::printStrings).curry("hello").accept("world");

甚至,这会起作用:

((Consumer2<String, String>)myClass::printStrings).curry("hello").accept("world");

在这种情况下,只要 Java 8 可以通过某种方式理解该函数类型。那么,问题是,最好的方法是什么,同时又能避免样板文件?

最佳答案

您不是在柯里化(Currying),而是在执行部分函数应用。这些操作是相关的,但并不完全相同。柯里化(Currying)意味着改变你的 Consumer2<T1, T2>Function<T1,Consumer1<T2>> .将该柯里化(Currying)函数应用于 T1 时值(value)你得到你的方法正在有效地做什么。

使用既定名称更容易bind由于将值绑定(bind)到函数的参数是一件很重要的事情,每个开发人员无需深入研究函数式编程的世界就可以理解。

也就是说,现在最好记住interface s 可以有 static方法,因此不需要此类实用程序类。此外,static仅返回其参数的方法本身用处不大,因此您可以将它与它应该提供的后续方法融合在一起。然后,它实现与实例方法相同的目的,可以作为简单的重载提供:

@FunctionalInterface
public interface Consumer2<T1, T2> {
void accept(T1 t1, T2 t2);

default Consumer1<T2> bind(T1 t1) {
return bind(this, t1);
}
static <T,U> Consumer1<U> bind(Consumer2<? super T, ? super U> c, T t) {
return u -> c.accept(t, u);
}
}
public interface Consumer1<T1> extends Consumer<T1> {}

public class MyClass {
public static void printStrings(String a, String b) {
System.out.println(a + ": " + b);
}

public static void main(String[] args) {
Consumer2.bind(MyClass::printStrings, "hello").accept("world");
}
}

另一方面,当您使用现有标准时 interface s Consumer BiConsumer 您别无选择,只能在与这些不同的类中提供实用方法 interface秒。但好消息是,那时很容易使解决方案保持一致,因为除了 static 之外,您不能提供任何其他东西。方法:

class FunctionUtil {
static <T,U> Consumer<U> bind(BiConsumer<? super T, ? super U> c, T t) {
return u -> c.accept(t, u);
}
}
public class MyClass {
public static void printStrings(String a, String b) {
System.out.println(a + ": " + b);
}

public static void main(String[] args) {
FunctionUtil.bind(MyClass::printStrings, "hello").accept("world");
}
}

关于java - 如何在 Java 8 中直接使用函数作为函数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32602010/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com