Java Generics and adding numbers together

前端 未结 7 1801
没有蜡笔的小新
没有蜡笔的小新 2020-11-27 07:58

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

相关标签:
7条回答
  • 2020-11-27 08:20

    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.

    0 讨论(0)
  • 2020-11-27 08:20

    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;
    }
    
    0 讨论(0)
  • 2020-11-27 08:25

    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.

    0 讨论(0)
  • 2020-11-27 08:26

    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.

    0 讨论(0)
  • 2020-11-27 08:29

    since the introduction of Java 8 streams and lambda you can have a shorter solution

    public interface Adder {
    
        static <E extends Number> E sumValues(Collection<E> objectsToSum, BinaryOperator<E> sumOp) {
            return objectsToSum.stream().reduce(sumOp).orElse(null);
        }
    }
    

    and use it as follows

    int sum = Adder.sumValues(List.of(4, 5, 6, 7), Integer::sum);
    

    Note, that Stream::reduce with just accumulator returns Optional that's why I used orElse(null), but I would recommend to send also zero value as parameter to Adder::sumValue

    0 讨论(0)
  • 2020-11-27 08:38

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题