Java 返回参数类型受泛型类型参数约束的lambda函数
假设我想编写一个方法Java 返回参数类型受泛型类型参数约束的lambda函数,java,generics,lambda,types,type-inference,Java,Generics,Lambda,Types,Type Inference,假设我想编写一个方法buildBiFxnWithSameTypeArgs,它生成一个双参数BiFunction,其输入参数的类型相同。具体是什么类型(即调用buildBiFxnWithSameTypeArgs时)是未知的——我只是希望编译器强制执行,每当调用buildBiFxnWithSameTypeArgs返回的函数时,提供给它的参数类型必须匹配。本质上,最终效果应该是lambda,相当于在方法定义中对两个参数的类型使用相同的泛型类型参数 我最初的尝试如下所示: public interfac
buildBiFxnWithSameTypeArgs
,它生成一个双参数BiFunction
,其输入参数的类型相同。具体是什么类型(即调用buildBiFxnWithSameTypeArgs
时)是未知的——我只是希望编译器强制执行,每当调用buildBiFxnWithSameTypeArgs
返回的函数时,提供给它的参数类型必须匹配。本质上,最终效果应该是lambda,相当于在方法定义中对两个参数的类型使用相同的泛型类型参数
我最初的尝试如下所示:
public interface ConstrainedBiFunction<I, O> extends BiFunction<I, I, O> {}
public static ConstrainedBiFunction<?, String> buildBiFxnWithSameTypeArgs() {
return (inputOne, inputTwo) -> String.valueOf(inputOne) + String.valueOf(inputTwo);
}
public void test() {
buildBiFxnWithSameTypeArgs().apply(Integer.valueOf(1), Integer.valueOf(2));
}
是否可以返回一个lambda函数,该函数的参数类型是推断的,然后以这种方式相互约束
编辑:为这个不太好的问题道歉;我有一个更复杂的问题,我试图抓住这个问题的本质,以便提出最简单的问题,但看起来我把问题简化得太多了。当然,我知道所有类都继承自对象
,因此在这个过于简化的问题呈现中,@shmosel和@JB提出的解决方案是有效的。一旦我能更好地提取原始问题,我将发布一个新问题。通配符的意思是“特定但未知的类型”。您不能传递任何满足类型为?
的参数的参数,因为它可能是错误的类型。将返回类型更改为ConstrainedBiFunction
,它将能够接受任何输入类型,因为每个类都隐式扩展对象
:
public static ConstrainedBiFunction<Object, String> buildBiFxnWithSameTypeArgs() {
return (inputOne, inputTwo) -> String.valueOf(inputOne) + String.valueOf(inputTwo);
}
publicstaticconstrainedbiffunction buildBiFxnWithSameTypeArgs(){
return(inputOne,inputwo)->String.valueOf(inputOne)+String.valueOf(inputwo);
}
注意,这仍然可以用于使用原则对输入类型有限制的方法。例如:
// input parameter must be of type Integer or any supertype,
// so that we can safely pass in an Integer
String combine(ConstrainedBiFunction<? super Integer, String> function) {
return function.apply(1, 2);
}
void test() {
ConstrainedBiFunction<Object, String> concat = buildBiFxnWithSameTypeArgs();
ConstrainedBiFunction<Integer, String> sum = (a, b) -> String.valueOf(a + b);
System.out.println(combine(concat)); // "12"
System.out.println(combine(sum)); // "3"
}
//输入参数的类型必须为Integer或任何超类型,
//这样我们就可以安全地传递一个整数
String combine(ConstrainedBiFunction正确地指出,对于遵循PECS规则的所有API,使用对象
作为输入类型应该足够了,但是可以修复您最初的尝试
您必须添加类型参数,而不是通配符,该参数允许调用者选择类型:
public interface ConstrainedBiFunction<I, O> extends BiFunction<I, I, O> {}
public static <T> ConstrainedBiFunction<T, String> buildBiFxnWithSameTypeArgs() {
return (inputOne, inputTwo) -> String.valueOf(inputOne) + String.valueOf(inputTwo);
}
public void test() {
ConstrainedBiFunction<Integer, String> f1 = buildBiFxnWithSameTypeArgs();
String s1 = f1.apply(1, 1);
ConstrainedBiFunction<String, String> f2 = buildBiFxnWithSameTypeArgs();
String s2 = f2.apply("hello ", "world");
}
您认为ConstrainedBUIFunction所有类最终都会从对象继承,因此,即使您传递香蕉和卡车,编译器也会将其推断为ConstrainedBUIFunction,除非您显式指定类型。
public interface ConstrainedBiFunction<I, O> extends BiFunction<I, I, O> {}
public static <T> ConstrainedBiFunction<T, String> buildBiFxnWithSameTypeArgs() {
return (inputOne, inputTwo) -> String.valueOf(inputOne) + String.valueOf(inputTwo);
}
public void test() {
ConstrainedBiFunction<Integer, String> f1 = buildBiFxnWithSameTypeArgs();
String s1 = f1.apply(1, 1);
ConstrainedBiFunction<String, String> f2 = buildBiFxnWithSameTypeArgs();
String s2 = f2.apply("hello ", "world");
}
Comparator<Integer> c1 = Comparator.naturalOrder();
c1.compare(10, 42);
Comparator<String> c2 = Comparator.naturalOrder();
c2.compare("foo", "bar");