Java 如何比较两个泛型类型参数

Java how to compare two generic type parameters

问题是编写泛型方法,将 T 限制为扩展 Number。只有一个字段变量 ArrayList。有一个将对象添加到 ArrayList 的 add 方法,然后是两个方法,一个是 returns ArrayList 中最大的方法,另一个是最小的方法。我的问题是在最大和最小方法中,我正在比较列表中的连续项目以搜索最大和最小,但它们是通用类型 T,我不能使用 < 和 >,并且 compareTo() 不起作用要么(我把这两个错误都放在提供的代码中)。有人可以看一下,让我知道哪里错了吗?

import java.util.ArrayList;

public class MyList<T extends Number> {
   private ArrayList<T> list;
   
   public MyList() {
      list = new ArrayList<T>();
   }
   
   public void add(T obj) {
      list.add(obj);
   }
   
   public T largest() {
      boolean onFirstObj = true;
      T largestVal;
      
      for (int i = 0; i < list.size(); i++) {
         if (onFirstObj) {
            largestVal = list.get(i);
            onFirstObj = false;
         }
         else {
            if (list.get(i) > largestVal) {
               largestVal = list.get(i);
            }
         }
      }
      
      return largestVal;
   }
   
   public T smallest() {
      boolean onFirstObj = true;
      T smallestVal;
      
      for (int i = 0; i < list.size(); i++) {
         if (onFirstObj) {
            smallestVal = list.get(i);
            onFirstObj = false;
         }
         else {
            if (list.get(i).compareTo(smallestVal) < 0) {
               smallestVal = list.get(i);
            }
         }
      }
      
      return smallestVal;
   }
}

< 和 > 运算符只能用于基本类型,Number class 本身没有实现 Comparable,所以不能使用 compareTo。

但是,如果您将 Comparable<T> 添加为类型绑定:

public class MyList<T extends Number & Comparable<T>> {
    ...
}

那么你可以使用compareTo方法:

public T largest() {
    boolean onFirstObj = true;
    T largestVal = null;

    for (T t : list) {
        if (onFirstObj) {
            largestVal = t;
            onFirstObj = false;
        } else {
            if (t.compareTo(largestVal) > 0) {
                largestVal = t;
            }
        }
    }

    return largestVal;
}

你可以这样做。

Number 具有访问原始值的方法(例如 doubleValue())。因此,您可以使用 doubleValue() 进行比较以处理整数和浮点类型。

之所以有效,是因为 int, double, float and long methods 被声明为 abstract,因此任何扩展 Number 的 class 必须为它们提供实现。 byteValue()shortValue() 只是调用 intValue() 并进行适当转换的方法。

如评论中所述,BigInteger and BigDecimal 的精度可以超过 doubleValue 可以容纳的精度,因此对于这些数据类型 解决方案注定要失败。

class MyList<T extends Number> {
    private ArrayList<T> list;
    
    public MyList() {
        list = new ArrayList<T>();
    }
    
    public void add(T obj) {
        list.add(obj);
    }
    
    public T largest() {
        T largestVal = list.get(0);
        for (int i = 1; i < list.size(); i++) {
            if (list.get(i).doubleValue() > largestVal.doubleValue()) {
                largestVal = list.get(i);
            }
        }
        return largestVal;
    }
    

    
    public T smallest() {
        T smallestVal = list.get(0);
        for (int i = 1; i < list.size(); i++) {
            if (list.get(i).doubleValue() < smallestVal.doubleValue()) {
                smallestVal = list.get(i);
            }   
        }
        return smallestVal;
    }
}