user1096734
user1096734

Reputation:

How to write a generic method in Java to support comparison and arithmetic operations

I want to write a generic method in java like below:

public <T extends Number & Comparable<T>> void test(T[] a){
    T b=a[0];
    if(a[0]>0){
        a[0]*=a[0];
        b+=a[1];
    }
}

Then later, I can supply either Integer[] or Double[] or other Number subtypes to the method. But the code I tried above gives me errors.

Please help me. Thank you.

Upvotes: 5

Views: 1701

Answers (3)

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147154

You've got Comparable, so if we has a zero, a[0]>0 could be replaced by a[0].compareTo(zero) > 0 (no, I think it's < 0, I can never remember). But now we've run out of useful stuff from Double and the like.

If Double and friends weren't java.lang.Comparable we could supply our own java.util.Comparator. That is we take the implementation of comparison outside of the data object. We can also do that addition and multiplication.

public interface Testor<T> { // Choose a better name...
    boolean isStriclyPositive(T value);
    T add(T lhs, T rhs);
    T square(T value);
}

static final Testor<Integer> INTEGER_TESTOR = new Testor<>() { // Java SE 7 diamond.
    public boolean isStriclyPositive(Integer value) { return value > 0; }
    public Integer add(Integer lhs, Integer rhs) { return lhs + rhs; }
    public Integer square(Integer value) { return value*value; }
}
// ... same for Double, etc.; can't use an enum :( ...

test(new Integer[] { 42, 1972, 86 }, INTEGER_TESTOR);

public <T> void test(T[] a, Testor<T> testor) {
    T b = a[0];
    if (testor.isStrictlyPositive(a[0])) {
        a[0] = testor.square(a[0]);
        b = testor.add(b, a[1]);
    }
}

Note for things like Short, summing two of them will give you an int.

(Usual Stack Overflow disclaimer: not so much as attempted to compile the code.)

Upvotes: 1

Martijn Courteaux
Martijn Courteaux

Reputation: 68847

You can't do this in Java with generics. That's a benefit of C++ for example.

In some way you can define this as "strange", because it is possible to use operators on Java's primitive wrappers. But that is because you can't use operators on java.lang.Number, the superclass of the primitive wrappers.

Some resources:

Upvotes: 3

ratchet freak
ratchet freak

Reputation: 48196

all types (including the inferred generic types) except the primitives are Objects which don't support the arithmetic operations (the wrapper classes use boxing/unboxing to get the known psuedo behavior)

and type erasure makes the compiled code use casts to get the proper behavior (i.e. at runtime the JVM doesn't know what type was passed in which it would need to know to get the proper boxing/unboxing behavior)

the only (real) solution is to provide implementations for all primitives you want to support

Upvotes: 5

Related Questions