Home > Net >  Java generics method fails on number comparison
Java generics method fails on number comparison

Time:03-16

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 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.

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;
}
  • Related