Java Generics and adding numbers together

2019-01-06 22:20发布

问题:

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?

回答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);
    }
}


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



回答3:

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.



回答4:

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.



回答5:

You should check runtime type (e.g. using instanceof) and cast to the known type and do appropriate addition operation. Not sure what will be type of result, taking in account that the list could contain a lot of different number types.



标签: java generics