将 lambda (Object -> Object) 传递给函数 Java
Pass lambda (Object -> Object) to function in Java
当我希望将 lambda 传递给函数,并且 lambda 接受并返回对象时,使用什么类型?
使用示例如下所示。我希望能够创建 Foo 的实例,在此示例中,每个实例都可以调用预先指定的 getter 函数。
class Foo() {
public ? lambdaFunction;
public Object doSomething(Object arbitraryClass);
return lambdaFunction(arbitraryClass);
}
foo.lambdaFunction = (Object object) -> ((SomeClass) object).getAttribite())
foo.doSomething(someClassInstance);
我有大量 类 具有可获取属性的数量,并且需要能够在不同的地方获取所有这些属性,但唯一改变的是 类 getter姓名。
java.util.function.Function
是要使用的类型。
class Foo {
private final Function<Object, ?> func;
public Foo(Function<Object, ?> func) {
this.func = func;
}
public Object doSomething(Object in) {
return func.apply(in);
}
}
但我怀疑你真的想要那个。 Java 是一种名义上类型化的语言——你应该使用名字,而且很多。 'Object' 意义不大。例如,假定该函数需要能够转换 any 对象,您传入的函数不能对该对象执行任何操作(好吧,除了 toString
, hashCode
,以及所有对象都有的其他方法)。该函数可以强制转换输入,但这很难看。
这听起来像是一个更好的计划:
class Foo<F, T> {
private final Function<? super F, ? extends T> func;
public Foo(Function<? super F, ? extends T> func) {
this.func = func;
}
public T doSomething(F in) {
return func.apply(in);
}
}
F 和 T 是 'from' 和 'to' 的缩写。它是 ? super F
的原因是因为如果您希望将字符串转换为整数,并且您有一个函数可以将任何对象转换为整数,这也很好:您希望它转换字符串或任何其超类型,对于 'to',任何子类型也可以。
根据您最近的评论扩展此答案:
Java 不是动态输入。没有随机的 mysterymeat 函数,这些函数在给定输入的情况下可能有意义也可能没有意义。因此,如果您想要一个 'function that describes a setter, e.g. that takes 2 input arguments',那么这是一个完全不同的概念:那将是一个需要 Receiver 和一个新值来设置的函数,而 returns 什么都不需要。 2 个输入,0 个输出。 j.u.f.Function
是 1 个输入,1 个输出。
2 个输入,0 个输出将是 java.util.function.BiConsumer<T, U>
。查看这些类型的 java.util.function API。
class Example {
private String name;
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public static final BiConsumer<Example, String> SETTER = Example::setName;
}
class SomeplaceElse {
void foo() {
Example e = new Example();
String n = "hello";
Example.SETTER.accept(e, n);
System.out.println(e.getName()); // prints 'hello'
}
}
java.util.function.Function<T,R>
,其中 T
是它的参数类型,R
是它的 return 类型。
但如果您真的打算拥有一个 public Function<Object,Object> lambdaFunction;
字段,那可能不是最好的设计,您应该使用您的实际类型,而不是来回转换。
对于评论中出现的扩展:查看包含的包,https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/function/package-summary.html看看还有什么“准备好了”。
对于有 2 个参数和 returning 的东西,你可以使用 BiFunction<T,U,R>
。对于有 2 个参数且 return 什么都没有,您可以使用 BiConsumer<T,U>
。如果您没有找到所需的内容,则可以创建自己的 interface
并将其标记为 @FunctionalInterface
. But that leads to a duplicate question,
当我希望将 lambda 传递给函数,并且 lambda 接受并返回对象时,使用什么类型?
使用示例如下所示。我希望能够创建 Foo 的实例,在此示例中,每个实例都可以调用预先指定的 getter 函数。
class Foo() {
public ? lambdaFunction;
public Object doSomething(Object arbitraryClass);
return lambdaFunction(arbitraryClass);
}
foo.lambdaFunction = (Object object) -> ((SomeClass) object).getAttribite())
foo.doSomething(someClassInstance);
我有大量 类 具有可获取属性的数量,并且需要能够在不同的地方获取所有这些属性,但唯一改变的是 类 getter姓名。
java.util.function.Function
是要使用的类型。
class Foo {
private final Function<Object, ?> func;
public Foo(Function<Object, ?> func) {
this.func = func;
}
public Object doSomething(Object in) {
return func.apply(in);
}
}
但我怀疑你真的想要那个。 Java 是一种名义上类型化的语言——你应该使用名字,而且很多。 'Object' 意义不大。例如,假定该函数需要能够转换 any 对象,您传入的函数不能对该对象执行任何操作(好吧,除了 toString
, hashCode
,以及所有对象都有的其他方法)。该函数可以强制转换输入,但这很难看。
这听起来像是一个更好的计划:
class Foo<F, T> {
private final Function<? super F, ? extends T> func;
public Foo(Function<? super F, ? extends T> func) {
this.func = func;
}
public T doSomething(F in) {
return func.apply(in);
}
}
F 和 T 是 'from' 和 'to' 的缩写。它是 ? super F
的原因是因为如果您希望将字符串转换为整数,并且您有一个函数可以将任何对象转换为整数,这也很好:您希望它转换字符串或任何其超类型,对于 'to',任何子类型也可以。
根据您最近的评论扩展此答案:
Java 不是动态输入。没有随机的 mysterymeat 函数,这些函数在给定输入的情况下可能有意义也可能没有意义。因此,如果您想要一个 'function that describes a setter, e.g. that takes 2 input arguments',那么这是一个完全不同的概念:那将是一个需要 Receiver 和一个新值来设置的函数,而 returns 什么都不需要。 2 个输入,0 个输出。 j.u.f.Function
是 1 个输入,1 个输出。
2 个输入,0 个输出将是 java.util.function.BiConsumer<T, U>
。查看这些类型的 java.util.function API。
class Example {
private String name;
public void setName(String name) { this.name = name; }
public String getName() { return name; }
public static final BiConsumer<Example, String> SETTER = Example::setName;
}
class SomeplaceElse {
void foo() {
Example e = new Example();
String n = "hello";
Example.SETTER.accept(e, n);
System.out.println(e.getName()); // prints 'hello'
}
}
java.util.function.Function<T,R>
,其中 T
是它的参数类型,R
是它的 return 类型。
但如果您真的打算拥有一个 public Function<Object,Object> lambdaFunction;
字段,那可能不是最好的设计,您应该使用您的实际类型,而不是来回转换。
对于评论中出现的扩展:查看包含的包,https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/function/package-summary.html看看还有什么“准备好了”。
对于有 2 个参数和 returning 的东西,你可以使用 BiFunction<T,U,R>
。对于有 2 个参数且 return 什么都没有,您可以使用 BiConsumer<T,U>
。如果您没有找到所需的内容,则可以创建自己的 interface
并将其标记为 @FunctionalInterface
. But that leads to a duplicate question,