【问题标题】:Lambda and Generic MethodsLambda 和通用方法
【发布时间】:2016-07-18 00:52:12
【问题描述】:

我正在学习 Lambda,但遇到了一些我无法解决的问题。

原来我的代码是:

package Lambdas;

@FunctionalInterface
interface NumericFunc2 {
    <T extends Number> T func(T n);
}

class Lbd_488_NumericFunc_SelfTest {
    public static void main(String args[]) {
        // This block lambda returns the smallest positive factor of a value.
        NumericFunc2 smallestF = (n) -> {
            double result = 1;
            // Get absolute value of n.
            n = n < 0 ? -n : n;
            for (int i = 2; i <= n / i; i++)
                if ((n % i) == 0) {
                    result = i;
                    break;
                }
            return result;
        };
        System.out.println("Smallest factor of 12 is " + smallestF.func(12));
        System.out.println("Smallest factor of 11 is " + smallestF.func(11));
    }
}

但是,我的操作员旁边不断出现错误(&lt;-/。 PS:即使我将其更改为&lt;T extends Double&gt;,我也会遇到同样的错误。

现在,如果我通过添加参数类型来更改代码,我会收到错误提示“目标方法是通用的”

即使我将其更改为 &lt;T extends Double&gt;,我也会遇到同样的错误。

package Lambdas;

@FunctionalInterface
interface NumericFunc2 {
    <T extends Number> T func(T n);
}

class Lbd_488_NumericFunc_SelfTest {
    public static void main(String args[]) {
        // This block lambda returns the smallest positive factor of a value.
        NumericFunc2 smallestF = (Double n) -> {
            double result = 1;
            // Get absolute value of n.
            n = n < 0 ? -n : n;
            for (int i = 2; i <= n / i; i++)
                if ((n % i) == 0) {
                    result = i;
                    break;
                }
            return result;
        };
        System.out.println("Smallest factor of 12 is " + smallestF.func(12));
        System.out.println("Smallest factor of 11 is " + smallestF.func(11));
    }
}

但是,如果我将类从非泛型更改为泛型,一切正常,就像下面的代码:

package Lambdas;

@FunctionalInterface
interface NumericFunc2<T extends Number>  {
    T func(T n);
}

class Lbd_488_NumericFunc_SelfTest {
    public static void main(String args[]) {
        // This block lambda returns the smallest positive factor of a value.
        NumericFunc2<Double> smallestF = (n) -> {
            double result = 1;
            // Get absolute value of n.
            n = n < 0 ? -n : n;
            for (int i = 2; i <= n / i; i++)
                if ((n % i) == 0) {
                    result = i;
                    break;
                }
            return result;
        };
        System.out.println("Smallest factor of 12 is " + smallestF.func(12));
        System.out.println("Smallest factor of 11 is " + smallestF.func(11));
    }
}

所以,我的问题是。我在代码的第一部分做什么?如何在非泛型类中正确使用具有泛型方法的 lambda?

【问题讨论】:

  • 提示 - 不要在 Lambada 中的 {} 内编写嘈杂的代码(超过一行),而是使用 methods()

标签: java generics lambda


【解决方案1】:

答案是您不能Number 对象执行这种数字运算。没有办法; 这与 lambdas 无关,而与 Number 抽象类无关,只是不提供这些功能。

在不知道Number 是什么类型的情况下,甚至没有任何方法可以获取Number 的绝对值。你看不到它是正还是负,你不能否定它,你不能加、减或乘。 唯一你可以用 Number 做的事情是将它转换成另一种原始类型,但你不能把它转换回来,你不能用它做数学。

【讨论】:

  • 好的,我明白你的意思了。但是,如果我从“Number”更改为“Double”,我仍然会收到同样的错误。
  • 此外,如docs.oracle.com/javase/specs/jls/se8/html/… 中所述,您可以看到 如果满足以下所有条件,则 lambda 表达式与函数类型一致: ...函数类型没有类型参数 因此不能将 lambda 分配给函数签名中包含类型变量的函数接口(这与具有通用函数接口不同)
  • 您的界面也不代表您认为的意思。当您编写&lt;T extends Number&gt; T func(T n); 时,您所说的是接口的每个实现(包括lambda)都必须有一个适用于any T extends Numberfunc 实现。即使您没有使用 lambda,您的界面也不会让您只实现 Number 的一个子类型。
  • 我怎样才能以一种有效的方式编写这段代码?保持方法泛型和类非泛型?
  • @Jack 的链接说你不能用 lambdas 做到这一点。如果您处理了Number 无法执行此操作的问题,您可以使用匿名类来执行此操作。
【解决方案2】:

根据JLS,泛型和lambda 不能一起工作。 This eclipse bug report 用一些代码示例讨论它。

为了让它工作,你必须回退到anonymous inner classes。 IE。你必须在你的函数周围写完整的new NumberFunc() {...} mambo-jambo。

我必须在方法主体中进行一些其他更改才能使其编译:

  • result 是盒装的Double,所以我可以将其转换为T
  • 在方法内部,我使用 n 的 doubleValue(),因为原始运算符不适用于 T extends Number

放在一起:

class Lbd_488_NumericFunc_SelfTest {
    public static void main(String args[]) {
        // This block lambda returns the smallest positive factor of a value.
        NumericFunc2 smallestF = new NumericFunc2() {
            public <T extends Number> T func(T n) {
                Double result = 1d;
                // Get absolute value of n.
                double nAbs = n.doubleValue() < 0 ? -n.doubleValue() : n.doubleValue();
                for (int i = 2; i <= nAbs / i; i++)
                    if ((nAbs % i) == 0) {
                        result = (double) i;
                        break;
                    }
                return (T) result;
            }
        };
        System.out.println("Smallest factor of 12 is " + smallestF.func(12));
        System.out.println("Smallest factor of 11 is " + smallestF.func(11));
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-19
    • 1970-01-01
    相关资源
    最近更新 更多