我在Java中学习lambda表达式,但是,我曾想过将它与泛型类型一起使用。 (例如int,String)。据我学习和研究在Java中使用lambda表达式,它必须在接口中声明。然后,定义您希望使用的实现。 (即(prototype args) -> {definition}
)。我已经尝试过编写类型问题的基本示例,如下所示。我刚想过将它与String
,int
类型一起用作练习。但是,我无法将通用类型初始化为0
。我可以为null
做。我不确定null
是否等于0
。如何解决问题?
public class Test<T,U> {
public static <T,U> void main(String[] args) {
Test myTest = new Test();
Str myHello = (message1, message2) -> {
System.out.println("Hello " + message1 + message2);};
myHello.welcome("Mr. ", "rickroll");
MyGen addition = (U... operationArgs) -> {
T sum = 0;
for (U i : operationArgs) {
sum += i;
}
return sum;};
System.out.println("2+3+4+5 = " + myTest.operate(addition, 2, 3, 4, 5));
System.out.println("A.....gl ?" + myTest.operate(addition, "b", "c", "d", "e", "f"));
}
private T operate(MyGen choice, U... args) {
return (T)choice.asYouWish(args);
}
interface Str {
public void welcome(String a, String b);
}
interface MyGen<T,U> {
public T asYouWish(U... args);
}
}
答案 0 :(得分:3)
您在不使用它们的情况下声明了几个类型参数,并且可能甚至不知道这些参数是独立的类型参数,尽管它们具有相同的名称。当你声明一个带有类型参数的类时,你必须在使用该类时声明类型参数。
所以当你定义一个像
这样的类时public class Test<T,U> {
public static <T,U> void main(String[] args) { … }
private T operate(MyGen choice, U... args) { … }
interface MyGen<T,U> {
public T asYouWish(U... args);
}
}
与声明
没什么不同public class Test<T,U> {
public static <A,B> void main(String[] args) { … }
private T operate(MyGen choice, U... args) { … }
interface MyGen<X,Y> {
public X asYouWish(Y... args);
}
}
为所有T
和U
命名并不会创建关系,但只会让人类的读者感到困惑。类的类型参数仅影响其非static
成员,而static
的唯一非Test
成员是方法operate
,它引用MyGen
没有实际的类型参数。
正确的用法是
private T operate(MyGen<T,U> choice, U... args) {
return choice.asYouWish(args);
}
所以你声明MyGen
参数必须根据Test
的参数化进行参数化,这现在可以让你在没有警告和没有类型转换的情况下调用asYouWish
。
应该强调的是,在为{{1}定义类型参数时,不能使用Test
的同一实例来使用String
和Integer
的方法。实例化T
时的{}和U
。
此外,Test
方法的类型参数独立于main
的类型参数,并且由于它们未在方法的签名中使用,因此非常无用。在lambda表达式中引用它们是没有意义的,即使lambda表达式的主体内没有编译器错误,在该范围内也没有该类型的实例可以使用该函数。
把它放在一起,你得到
Test
您可以通过简单地将public class Test<T,U> {
public static void main(String[] args) {
Str myHello = (message1, message2) ->
System.out.println("Hello " + message1 + message2);
myHello.welcome("Mr. ", "rickroll");
{
Test<Integer,Integer> myTest = new Test();
MyGen<Integer,Integer> addition = operationArgs -> {
int sum = 0;
for(int i: operationArgs) sum += i;
return sum;
};
System.out.println("2+3+4+5 = " + myTest.operate(addition, 2, 3, 4, 5));
}
{
Test<String,String> myTest = new Test();
MyGen<String,String> addition = operationArgs -> {
String sum = "";
for(String i: operationArgs) sum += i;
return sum;
};
System.out.println("A.....gl ?"
+ myTest.operate(addition, "b", "c", "d", "e", "f"));
}
}
private T operate(MyGen<T,U> choice, U... args) {
return choice.asYouWish(args);
}
interface Str {
public void welcome(String a, String b);
}
interface MyGen<X,Y> {
public X asYouWish(Y... args);
}
}
转换为通用Test
方法来消除对operate
实例进行参数化的要求,因为无论如何都不需要实例。如果要定义通用static
函数,则必须抽象MyGen
运算符,与+
情况下的外观不同,Java中没有运算符重载。
此外,您必须在不需要中性元素的情况下实现它,因为String
在尝试对字符串使用相同的函数时不会神奇地变成空字符串。
0
这仅用于演示目的,因为已经完成了这项工作,例如您可以将import java.util.function.BinaryOperator;
public class Test {
public static void main(String[] args) {
Str myHello = (message1, message2) ->
System.out.println("Hello " + message1 + message2);
myHello.welcome("Mr. ", "rickroll");
example(Integer::sum, "2+3+4+5 = ", 2, 3, 4, 5);
example(String::concat, "A.....gl ?", "b", "c", "d", "e", "f");
}
private static <E> void example(BinaryOperator<E> plus, String head, E... values) {
MyGen<E,E> addition = args -> {
E sum=args[0];
for(int ix=1; ix<args.length; ix++) sum = plus.apply(sum, args[ix]);
return sum;
};
System.out.println(head + Test.operate(addition, values));
}
private static <T,U> T operate(MyGen<T,U> choice, U... args) {
return choice.asYouWish(args);
}
interface Str {
public void welcome(String a, String b);
}
interface MyGen<X,Y> {
public X asYouWish(Y... args);
}
}
方法更改为:
example