'Java generics method fails on number comparison
See the tiny method below. The boo1 = ... line goes fine, probably as it does object ID comparison. The second boo2 = ... line gives a compile error "Operator > cannot be applied to T,T". I don't understand why. After all T extends Number (as you can see in the method signature), so comparisons like > should be possible. What am I doing wrong?
public static <T extends Number> int[] where(T[] arr, T val) {
if (arr == null || arr.length == 0) return null;
boolean boo1 = arr[0] == val; //Compiles happily, as does "!="
boolean boo2 = arr[0] > val; //Doesn't compile (nor does ">=", "<", "<="
return null;
}
Solution 1:[1]
What am I doing wrong?
You're assuming that the relational operators support Number operands; they don't. Only Numbers that box primitive types (e.g. Integer, Long) do; others such as BigInteger don't.
You can add an additional bound to T to require it to be Comparable:
<T extends Number & Comparable<T>>
And you can pass in any types that are both Numbers and are Comparable: this includes Integer, Long, BigInteger etc.
Then you can use:
arr[0].compareTo(val) > 0
(but you might care to watch out for nulls).
Also, you shouldn't be using == and != to check for equality/inequality: use equals instead:
arr[0].equals(val) // Instead of ==
!arr[0].equals(val) // Instead of !=
You can, alternatively, use arr[0].compareTo(val) ==/!= 0. That may be better, in fact, because e.g. BigInteger and BigDecimal have equals methods that consider scale, so [1.00].equals([1.0]) is false, whereas [1.00].compareTo([1.0]) == 0 is true. Ultimately, it depends on what you're trying to achieve as to which way to choose.
Solution 2:[2]
Try it this way:
public static <T extends Number> int[] where(T[] arr, T val) {
if (arr == null || arr.length == 0) return null;
boolean boo1 = arr[0] == val; //Compiles happily, as does "!="
boolean boo2 = arr[0].intValue() > val.intValue();
// Or doubleValue()
return null;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Stewart |
