Java Generics and adding numbers together
I would like to generically add numbers in java. I'm running into difficulty because the Numbers class doesn't really support what I want to do. What I've tried so far is this:
public class Summer<E extends Number> {
public E sumValue(List<E> objectsToSum) {
E total = (E) new Object();
for (E number : objectsToSum){
total += number;
}
return null;
}
Obviously this will not work. How can I go about correcting this code so I could be given a list of <int>
or <long>
or whatever and return the sum?
Solution 1:
In order to calculate a sum generically, you need to provide two actions:
- A way to sum zero items
- A way to sum two items
In Java, you do it through an interface. Here is a complete example:
import java.util.*;
interface adder<T extends Number> {
T zero(); // Adding zero items
T add(T lhs, T rhs); // Adding two items
}
class CalcSum<T extends Number> {
// This is your method; it takes an adder now
public T sumValue(List<T> list, adder<T> adder) {
T total = adder.zero();
for (T n : list){
total = adder.add(total, n);
}
return total;
}
}
public class sum {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(4);
list.add(8);
CalcSum<Integer> calc = new CalcSum<Integer>();
// This is how you supply an implementation for integers
// through an anonymous implementation of an interface:
Integer total = calc.sumValue(list, new adder<Integer>() {
public Integer add(Integer a, Integer b) {
return a+b;
}
public Integer zero() {
return 0;
}
});
System.out.println(total);
}
}
Solution 2:
As Number class does not expose interface for performing calculations, the only way to solve this problem is to create classes which encapsulates required operations for each supported numeric type. Than in your class you will need to use specific type.
Solution 3:
Number has intValue(), floatValue(), doubleValue(), longValue, and shortValue(). Choose one and use it. For example,
double total;
total += number.doubleValue();
return total;
Also, java generics are in no way equivalent to c++ templates. You can not allocate new instances of a java generic type. This can never work:
E hoot = (E) new Object();
Finally, long
, short
, int
, double
, and float
are not class types; they are primitive types. As such they are not available for use with Java generics.
Solution 4:
below method get numbers such as int, float, etc and calculate sum of them.
@SafeVarargs
private static <T extends Number> double sum(T... args) {
double sum = 0d;
for (T t : args) {
sum += t.doubleValue();
}
return sum;
}
Solution 5:
Number doesn't support any operations so you need to cast the values to the types required. e.g. If Number is a BigDecimal, there is no +=
operator.