【问题标题】:How to perform Arithmetic operations on Generic type in JAVA?如何在 JAVA 中对泛型类型执行算术运算?
【发布时间】:2021-05-03 11:18:57
【问题描述】:

我有一个包含两个数据成员的通用类。这是我写的一段代码

class Calculator<T> {
    T num1, num2;
    public Calculator(T num1, T num2) {
        this.num1 = num1;
        this.num2 = num2;
    }
}

我想对 num1、num2 进行简单的算术运算,比如加减法,我还想进行简单的二元运算,比如 > 但由于是泛型,所以不允许这样做。

但这是不允许的,那么谁能告诉我如何执行这些任务?

【问题讨论】:

  • 减法对于Calculator&lt;Cat&gt;意味着什么?由于T 不受限制,它可以是任何东西,例如Cat。您尝试做的事情对编译器毫无意义。 --- 由于泛型不能使用 primitive 类型,您将强制所有值自动装箱,这也不好。只需创建一个适用于广泛值类型的计算器,例如BigDecimal。如果要使用原语,请使用longdouble。任何其他类型都是不必要的,因为当您拥有 long 版本时,您实际上并不需要 int 版本。

标签: java class generics


【解决方案1】:

简短的回答是你不能。

长答案是您可以将T 的类型限制为特定类型。

  • 为了比较,您可以将其限制为T extends Comparable&lt;T&gt;,之后您可以num1.compareTo(num2)
  • 对于加法和减法,您可以将其限制为T extends Number,然后对取自 number 的原始类型进行算术运算:
int a = num1.intValue();
int b = num2.intValue();

int sum = a + b;
int diff1 = a - b;
int diff2 = b - a;

最后一种方法的问题是将算术结果返回到T,您需要为此添加一个方法。

【讨论】:

    【解决方案2】:

    您应该使用方法实现接口,例如:

    interface MyNumber {
       MyNumber add(MyNumber a, MyNumber b);
       ...
    }
    

    然后就可以使用了

       class Calculator<T extends MyNumber> {
        T num1, num2;
        public Calculator(T num1, T num2) {
            this.num1 = num1;
            this.num2 = num2;
        }
      }
    

    当然,你所有的类都应该实现 MyNumber

    【讨论】:

      【解决方案3】:

      不可能;这是您尝试做的事情所固有的:将两个数字相加并不是您可以做的事情;您不能编写可以将 2 个任意 'T' 加在一起的代码。

      假设你写了一些可以做到的假设代码,然后我邀请“二维空间复数”,它有一个实部、虚部和一个超虚部:5 + 10i + 20j 就是一个例子这样一个数字。您可以按照自己的想法将任何超复数相加; 5 + 10i + 20j + 1 + 2i + 3j6 + 12i + 23j

      如果不首先知道我编造的这个超复数的存在,显然不可能编写出可以做到这一点的代码。

      换句话说,Calculator 不能代表任意“支持加法的事物”。您可以专门为 SuperComplex 数字构建一个计算器,并编写一个包含 List&lt;T&gt;Calculator&lt;T&gt; 的代码,从而能够产生总和:

      interface Calculator<T> {
         //  note: Interface. You don't implement it, the user of this library does.
      
         T add(T a, T b);
         T zero();
      }
      
      class ListSummer<T> {
          int sum(List<T> list, Calculator<T> calculator) {
              T answer = calculator.zero();
              for (T item : list) answer = calculator.add(answer, item);
              return answer;
          }
      }
      

      然后你可以发布这个库,我可以下载它,然后写这个:

      class SuperComplex {
          double real, i, j;
      }
      
      class SuperComplexCalculator implements Calculator<SuperComplex> {
          public SuperComplex zero() { return new SuperComplex(); }
          public SuperComplex add(SuperComplex a, SuperComplex b) {
              double real = a.real + b.real;
              double i = a.i + b.i;
              double j = a.j + b.j;
              return new SuperComplex(real, i, j);
          }
      }
      

      然后使用您的 ListSummer 代码,传入我的计算器。

      【讨论】:

        【解决方案4】:

        你可以提供一组操作:

        interface Operations<T> {
          T add(T a, T b);
          T times(T a, T b);
          // ...
        }
        

        针对特定类型的实现:

        class IntOperations implements Operations<Integer> {
          Integer add(Integer a, Integer b) { return a + b; }
          Integer times(Integer a, Integer b) { return a * b; }
          // ...
        }
        

        然后将 this 的一个实例传递给Calculator

        public Calculator(T num1, T num2, Operations<T> ops) {
        

        并根据需要调用ops 上的方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-01-11
          • 2020-10-11
          • 1970-01-01
          • 2010-10-19
          • 1970-01-01
          • 2011-05-01
          • 1970-01-01
          • 2016-06-10
          相关资源
          最近更新 更多