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;
}
CodePudding user response:
What am I doing wrong?
You're assuming that the relational operators support Number
operands; they don't. Only Number
s 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 Number
s 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.
CodePudding user response:
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;
}