2012-03-24 70 views
3

我正在从C++学习Java中的泛型,并且很困惑如何在没有运算符重载的情况下进行数学运算。假设我想编写一个sumList类,它只是一个使用求和方法的列表。Java泛型,添加列表中的所有整数/向量

public class sumList<T extends CanAdd<T>> { 
    private List<T> list; 

    public sumList() { 
     list = new List<T>(); 
    } 

    public void addElement(T t) { 
     list.add(t); 
    } 

    public T getSum() { 
     T ans = null; 
     for (T t : list) { 
      if (ans == null) { 
       ans = t; 
      } else { 
       ans = ans.plus(t); 
      } 
     } 
     return ans; 
    } 
} 

和我使用的接口很简单:

public interface CanAdd<T> 
{ 
    // returns a new T that's the sum of the object + other 
    public T plus(T other); 
} 

所以这是很简单的,当我创建sumList S的我创建类,一个Vector或例如Point,因为我可以添加接口定义的加号方法。但是,如何更改sumList以便我还可以创建sumList<Double>sumList<Integer>

编辑:修正小错误。

+0

但是,你已经有什么阻止你实例化'sumList '和'sumList '? – 2012-03-24 01:19:18

+0

@Kirk:'Integer'和'Double'都不能实现'canAdd'。 – 2012-03-24 01:21:12

+0

我想你有一个错误:不应该是'ans = ans.plus(t);'而不是'ans = ans.add(t);'? – 2012-03-24 01:22:26

回答

3

正如Kaleb所说,如果你只需要这个与Java数字一起工作,那么你不应该担心一个接口,并简单地使用T extends Number。

但是,如果你真的想使这个更通用并使用你的canAdd接口,那么你需要围绕Number对象编写一个包装类,并使用它。

编辑

也许你正在寻找了错误的方式。与其让填充列表的类具有特定行为(在这种情况下为总和),您应该从函数式编程中借用一些有用的技巧。

您可以在Java中编写映射,缩小和过滤方法。你有一些样板让你可以使用它们,但是你可以轻松地创建一个reduce函数,用于你想要求和的每种类型的对象,然后将它应用到你的列表中。

+0

“包装类”听起来有点过分了...... Java是少数几种语言之一,它实际上是一项艰巨的任务:/ – 2012-03-24 01:27:39

+0

基本上你需要的是扩展方法。 java不提供开箱即用的东西。希望在未来的版本中,谁知道。目前你可能想看看提供扩展方法的面向方面编程框架。但这对您的用例来说会更有害。 – 2012-03-24 01:29:12

+1

查看我编辑的答案替代解决方案 – 2012-03-24 01:46:42

0

为什么不使用Double和Integer,Number的基类?

public class sumList<T extends Number>

这样的话,没有必要实施canAdd接口或使用双打和整数与该接口创建包装。

编辑:但如果你真的需要使这个工作的自定义类,我认为你必须做一个包装类,提供必要的canAdd接口。或者,使用Scala或Groovy等语言,可以访问mixin!

+0

但是,如何将'sumList'与像Vector这样的自定义类一起使用呢? – 2012-03-24 01:21:47