Reputation: 29
I am learning Lambda and I came across something I cannot solve.
Originally my code was:
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));
}
}
However, I keep getting errors next to my operators (<
, -
, /
).
PS:Even if I change it to <T extends Double>
I get the same errors.
Now, if I change the code by adding the parameter type, I get an error saying that the "Target Method is Generic":
Even if I change it to <T extends Double>
I get the same errors.
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));
}
}
But, if I change the class from non-generic to generic, everything works fine, like this code:
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));
}
}
So, my question is. What I am doing work on my first part of the code? How can I use lambdas with generic methods, inside non-generic classes properly?
Upvotes: 2
Views: 1075
Reputation: 7166
According to the JLS, generics and lambdas won't work together. This eclipse bug report discusses it with some code examples.
In order to make it work, you have to fall back to anonymous inner classes. I.e. you have to write the full new NumberFunc() {...}
mambo-jambo around your function.
I had to make some other changes in the body of the method to make it compile:
result
is the boxed Double
so I can cast it to T
T extends Number
.Putting it together:
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));
}
}
Upvotes: 0
Reputation: 198033
The answer is that you cannot do this sort of numeric operation on a Number
object. There is no way; this has nothing to do with lambdas and everything to do with the Number
abstract class just not providing those features.
There is not even any way to get the absolute value of a Number
without knowing what kind of Number
it is. You can't see whether it's positive or negative, you can't negate it, you can't add, subtract, or multiply it. The only thing you can do with a Number
is convert it into another primitive type, but you can't convert it back and you can't do math with it.
Upvotes: 3