Java泛型并将数字加在一起

时间:2011-12-29 15:36:42

标签: java generics

我想在java中一般添加数字。我遇到了困难,因为Numbers类并不真正支持我想做的事情。到目前为止我尝试过的是:

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;

    }

显然这不起作用。如何更正此代码,以便为我提供<int><long>或其他任何内容的列表并返回总和?

7 个答案:

答案 0 :(得分:11)

为了一般地计算总和,您需要提供两个动作:

  • 一种总计零项的方法
  • 一种将两个项目相加的方法

在Java中,您可以通过界面完成。这是一个完整的例子:

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

答案 1 :(得分:3)

由于Number类没有公开用于执行计算的接口,解决此问题的唯一方法是创建封装每个支持的数字类型所需操作的类。比你班上的你需要使用特定的类型。

答案 2 :(得分:1)

Number不支持任何操作,因此您需要将值强制转换为所需的类型。例如如果Number是BigDecimal,则没有+=运算符。

答案 3 :(得分:1)

Number具有intValue(),floatValue(),doubleValue(),longValue和shortValue()。选择一个并使用它。例如,

double total;
total += number.doubleValue();

return total;

此外,java泛型绝不等同于c ++模板。您无法分配Java泛型类型的新实例。这永远不会起作用:

E hoot = (E) new Object();

最后,longshortintdoublefloat不是类类型;它们是原始类型。因此,它们不能与Java泛型一起使用。

答案 4 :(得分:1)

以下方法获取int,float等数字并计算它们的总和。

@SafeVarargs
private static <T extends Number> double sum(T... args) {
    double sum = 0d;
    for (T t : args) {
        sum += t.doubleValue();
    }
    return sum;
}

答案 5 :(得分:0)

您应该检查运行时类型(例如,使用instanceof)并转换为已知类型并执行适当的添加操作。考虑到列表可能包含许多不同的数字类型,不确定结果类型是什么。

答案 6 :(得分:0)

由于Java 8流和lambda的引入,您可以有一个较短的解决方案

public static class Summer<E extends Number> {

    public E sumValue(List<E> objectsToSum, BinaryOperator<E> sumOp) {
        return objectsToSum.stream().reduce(sumOp).orElse(null);
    }
}

并按以下方式使用

int sum = new Summer<Integer>().sumValue(List.of(4, 5, 6, 7), Integer::sum);

请注意,只有累加器的Stream::reduce返回Optional,这就是为什么我使用orElse(null)的原因,但是我建议也将零值作为参数发送给Summer::sumValue