通用

时间:2016-07-12 07:48:48

标签: java generics lambda java-8

我在Java中学习lambda表达式,但是,我曾想过将它与泛型类型一起使用。 (例如int,String)。据我学习和研究在Java中使用lambda表达式,它必须在接口中声明。然后,定义您希望使用的实现。 (即(prototype args) -> {definition})。我已经尝试过编写类型问题的基本示例,如下所示。我刚想过将它与Stringint类型一起用作练习。但是,我无法将通用类型初始化为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);
    }
}

1 个答案:

答案 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);
    }
}

为所有TU命名并不会创建关系,但只会让人类的读者感到困惑。类的类型参数仅影响其非static成员,而static的唯一非Test成员是方法operate,它引用MyGen没有实际的类型参数。

正确的用法是

private T operate(MyGen<T,U> choice, U... args) {
    return choice.asYouWish(args);
}

所以你声明MyGen参数必须根据Test的参数化进行参数化,这现在可以让你在没有警告和没有类型转换的情况下调用asYouWish

应该强调的是,在为{{1}定义类型参数时,不能使用Test的同一实例来使用StringInteger的方法。实例化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