joy
joy

Reputation: 57

How to perform Arithmetic operations on Generic type in JAVA?

I have a Generic class with two data members. Here is a piece of code that I have written

class Calculator<T> {
    T num1, num2;
    public Calculator(T num1, T num2) {
        this.num1 = num1;
        this.num2 = num2;
    }
}

I want to perform simple arithmetic on num1, num2 like addition and subtraction, and I also want to perform simple binary operations like < and > but as it is generic type, it's not allowed to do that.

But it's not allowed, then can anyone tell me how I can perform these tasks?

Upvotes: 0

Views: 1851

Answers (3)

Andy Turner
Andy Turner

Reputation: 140318

You could provide a set of operations:

interface Operations<T> {
  T add(T a, T b);
  T times(T a, T b);
  // ...
}

Implement for a specific type:

class IntOperations implements Operations<Integer> {
  Integer add(Integer a, Integer b) { return a + b; }
  Integer times(Integer a, Integer b) { return a * b; }
  // ...
}

Then pass an instance of this into Calculator:

public Calculator(T num1, T num2, Operations<T> ops) {

and invoke the method on ops as required.

Upvotes: 0

rzwitserloot
rzwitserloot

Reputation: 102902

Not possible; and that is inherent in what you are trying to do: The job of adding 2 numbers together is not something you can just do; you can't write code that can add 2 arbitrary 'T's together.

Imagine you wrote some hypothetical code that can do it, and then I invite '2-d space complex numbers', which have a real component, and imaginary component, and a super-imaginary component: 5 + 10i + 20j is an example of such a number. You can add any supercomplex numbers together the way you'd think; 5 + 10i + 20j + 1 + 2i + 3j is 6 + 12i + 23j.

It's obviously not possible to write code that can do this without first knowing that this supercomplex number thing I made up exists.

In other words, a Calculator for arbitrary 'things that support addition' cannot be. You COULD build a calculator specifically for SuperComplex numbers, and have code that takes in, say, a List<T> along with a Calculator<T> and is thus able to produce, say, the sum:

interface Calculator<T> {
   //  note: Interface. You don't implement it, the user of this library does.

   T add(T a, T b);
   T zero();
}

class ListSummer<T> {
    int sum(List<T> list, Calculator<T> calculator) {
        T answer = calculator.zero();
        for (T item : list) answer = calculator.add(answer, item);
        return answer;
    }
}

and then you can publish this library, and I can download it, and write this:

class SuperComplex {
    double real, i, j;
}

class SuperComplexCalculator implements Calculator<SuperComplex> {
    public SuperComplex zero() { return new SuperComplex(); }
    public SuperComplex add(SuperComplex a, SuperComplex b) {
        double real = a.real + b.real;
        double i = a.i + b.i;
        double j = a.j + b.j;
        return new SuperComplex(real, i, j);
    }
}

and then use your ListSummer code, passing in my calculator.

Upvotes: 0

Jeroen Steenbeeke
Jeroen Steenbeeke

Reputation: 4013

The short answer is you can't.

The long answer is that you can limit the type of T to a specific type.

  • For comparison, you could limit it to T extends Comparable<T> after which you could num1.compareTo(num2)
  • For addition and subtraction, you could limit it to T extends Number, and then do arithmetic on the primitive types taken from number:
int a = num1.intValue();
int b = num2.intValue();

int sum = a + b;
int diff1 = a - b;
int diff2 = b - a;

The problem with this last approach is turning the arithmetic result back to T, you'd need to add a method for that.

Upvotes: 1

Related Questions