使用泛型在Java中实现一个包含int和double并返回sum的列表



我正试图为一个名为Number的类编写一个简单的程序,该类使用泛型参数。我的想法是,我想把这些Number存储在List中,这样我就可以遍历它并求和。

我的列表是[2,3.4,4,5]类型。这是int和doubles的混合。我当前的代码如下导入java.util.*;

class Number<T> {
    T n;
    Number(T n) {
        this.n=n;
    }
    public T getnumber(){
        return n;
    }
    public String toString() {
        return n.toString();
    }
}
public class GenericsWildcards {
    public static void main(String[] args) {
        Number num1=new Number(5);
        Number num2= new Number(5.4);
        Number num3=new Number(1.2);
        List<Number> list=new ArrayList<Number>();
        list.add(num1);
        list.add(num2);
        list.add(num3);
        System.out.println(list);//prints correctly
        double sum=0;
        for (Number i : list){
            sum+=i.getnumber();//compile error here
        }
        System.out.println("sum is "+ sum);
        }
    }

系统输出正确打印列表,但我无法getnumber,因为它是类型Object的返回。我试着把它选为双倍sum+=(Double)i.getnumber();,但还是无济于事。我该怎么解决这个问题?任何改进更好实现的想法都将不胜感激。感谢

您不需要创建自己的Number类来实现这一点。您只需使用Number的Java Library类就可以在自动装箱的帮助下实现这一点。

        public static void main(String[] args) {
            List<Number> list = new ArrayList<Number>();
            list.add(5);
            list.add(5.4);
            list.add(1.2);
            System.out.println(list);
            double sum = 0;
            for(Number i : list){
                sum += i.doubleValue();
            }
            System.out.println("sum is " + sum);
        }

我使用doubleValue()将数字相加,同时保留小数信息。

您在创建Number实例时忽略了泛型类型参数,这就是它们返回Objects的原因。

您知道Java的API已经有一个Number类,它是所有原始数字类型(Integer、Float、Double、Long等)的所有引用类型的超类吗?

您正在使用您的Number作为原始类型(您没有指定t),因此所有的遗传方法都恢复为Object,这就是getNumber()为您返回Object的原因。

步骤1:放弃Number类,转而使用java的java.lang.Number

步骤2:利用自动装箱:

Number num1 = 5; // Integer
Number num2 = 5.4; // Double
Number num3 = 1.2; // Double

步骤3:求和列表中数字的doubleValue()的返回值

您不想要泛型,您可能想要子类化,即使这样,您也需要包装求和运算。例如,给定您的代码,您实际想要编写的是

Number<Integer> num1 = new Number<Integer>(5);
Number<Double> num2 = new Number<Double>(5.4);

请注意,我们必须为泛型指定类型,也就是说num1Number<Integer>num2Number<Integer>,但是,如果我们想创建列表,这会引起问题,因为num1num2是不同的类型。

因为Java并不总是有泛型,所以List、ArrayList等类过去只接受对象,因此,如果不传入类型,则默认为对象。因此,您的代码相当于

Number<Object> num1 = new Number<Object>(5);
Number<Object> num2 = new Number<Object>(5.4);
...
List<Number<Object>> list = new ArrayList<Number<Object>>();

事实上,在Java中实现您所描述的是不可能的,但这是可取的,因为否则在编译时就不可能知道i.getnumber()是什么类型,因此程序无法键入check(它怎么知道您只添加了int和double)。

附言:你可能在寻找访客模式http://en.wikipedia.org/wiki/Visitor_pattern#Java_example

最新更新