简体   繁体   English

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

[英]Java how to compare two generic type parameters

The problem is to write generic method, with T constrained to extends Number.问题是编写泛型方法,将 T 约束为扩展 Number。 Only have a single field variable ArrayList.只有一个字段变量ArrayList。 Have an add method that adds objects to the ArrayList, and then two methods, one that returns the largest in the ArrayList and the other the smallest.有一个将对象添加到 ArrayList 的 add 方法,然后是两个方法,一个返回 ArrayList 中最大的一个,另一个返回最小的。 My problem is in the largest and smallest methods where I am comparing successive items in the list with each other searching for the largest and smallest, but they are of generic type T and I cannot use < and >, and compareTo() does not work either (I put both errors in the code provided).我的问题是在最大和最小的方法中,我将列表中的连续项相互比较以搜索最大和最小,但它们是通用类型 T,我不能使用 < 和 >,并且 compareTo() 不起作用要么(我把这两个错误都放在提供的代码中)。 Can someone take a look and let me know where I am going wrong?有人可以看看并让我知道我哪里出错了吗?

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

The < and > operators can only be used with primitive types, and the Number class does not implement Comparable itself, so you can't use compareTo. < 和 > 运算符只能用于原始类型,而Number类本身没有实现Comparable ,因此不能使用 compareTo。

However if you add Comparable<T> as a type bound:但是,如果您添加Comparable<T>作为类型绑定:

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

then you can use the compareTo method:那么你可以使用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;
}

You could do it like this.你可以这样做。

Number has the methods for accessing primitive values (eg doubleValue()). Number 具有访问原始值的方法(例如 doubleValue())。 So you can use doubleValue() for the compare to handle both integer and floating types.因此,您可以使用doubleValue()进行比较来处理整数和浮点类型。

It works because the int, double, float and long methods are declared abstract so any class that extends Number must provide implementations for them.它之所以有效,是因为int, double, float and long methods被声明为abstract int, double, float and long methods ,因此任何扩展Number类都必须为它们提供实现。 byteValue() and shortValue() are simply methods that call intValue() and are cast appropriately. byteValue()shortValue()只是调用intValue()并适当转换的方法。

As mentioned in the comments, BigInteger and BigDecimal can have precisions that exceed what the doubleValue can accommodate so for those datatypes this solution is destined to fail.正如评论中提到的, 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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM