如何在java中的Generic数组中使用compareTo?

时间:2011-10-17 15:13:10

标签: java arrays generics compareto

我想弄清楚如何比较T []数组中的两个项目,这就是我所拥有的:

public static <T extends Comparable< ? super T>> T getLargest(T [] a, int low, 
               int high){
    if(low>high)
            throw new IllegalArgumentException();
    T[] arrCopy = (T[]) new Object[high-low];
    for(int i=low;i<high;i++){
        if(a[i].compareTo(a[i-1])>0)
            arrCopy[i]=a[i];
        else
            arrCopy[i]=a[i+1];
    }
    return arrCopy[0];
}

然后我收到错误:Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;

关于我如何解决这个问题的任何想法?

6 个答案:

答案 0 :(得分:5)

您可以像这样分配数组:

@SuppressWarnings("unchecked")
T[] arrCopy = (T[]) Array.newInstance(a.getClass().getComponentType(), high-low);

虽然未经检查的警告是必要的,但实际上这应该是安全的。

顺便说一句,如果你想找到一个数组中最大的元素,这里有一个oneliner:

public static <T extends Comparable<T>> T max(final T[] data) {
    return Collections.max(Arrays.asList(data));
}

对于完整的问题,您可以使用这两个中的一个(它们是等效的):

public static <T extends Comparable<T>> T maxA(final T[] data,int from, int to) {
    return Collections.max(Arrays.asList(Arrays.copyOfRange(data, from, to)));
}
public static <T extends Comparable<T>> T maxB(final T[] data,int from, int to) {
    return Collections.max(Arrays.asList(data).subList(from, to));
}

答案 1 :(得分:2)

当您只关心1个对象时,不确定为什么要创建一个完整的新数组,但问题与泛型无关。您无法将Object[]转换为某些更具体的类型,例如String[],就像您无法编写String s = new Object()一样。

如果您只关心最大值,那么仅跟踪1个值(到目前为止看到的最大值),而不是整个数组,会更有意义。

答案 2 :(得分:2)

你在这里得到错误:

T[] arrCopy = (T[]) new Object[high-low];

您不能将所有对象(java.lang.object)的母对象强制转换为将java.lang.comparable作为最小公分母的任何对象,因此抛出异常。对象(如在java.lang.object中)不实现java.lang.comparable。

在您的具体示例中,您需要创建一个T数组(或至少java.lang.comparable)。

答案 3 :(得分:2)

没有理由假设Object个实例的数组适合作为Comparable个实例的数组进行处理。您强行将Object强制转换为T,我们希望扩展为Comparable,但此处甚至不需要取消选中的作业。

相反,请考虑不复制任何数组的实现:

public static <T extends Comparable<? super T>>
T getLargest(T[] a, int first, int last)
{
  // Don't tolerate an empty range:
  if (first >= last)
    throw new IllegalArgumentException();
  // Eventually checked by subsequent use of array index operator:
  if (first < 0 || first >= a.length ||
      last < 0 || last >= a.length)
    throw new IndexOutOfBoundsException();

  T largest = a[first];
  while (++first != last)
  {
    final T candidate = a[first];
    if (candidate.compareTo(largest) > 0)
      largest = candidate;
  }
  return largest;
}

或者,使用Collections#max(),在通过Arrays#asList()后将您的数组视为List

答案 4 :(得分:2)

使用:

public static <T extends Comparable<? super T>> T max(final T[] data, int fromIndex, 
               int toIndex) {
    return Collections.max(Arrays.asList(data).subList(fromIndex, toIndex));
}

答案 5 :(得分:0)

只需将new Object[high-low];更改为new Comparable[high-low];即可。泛型被删除到下限,因此T被删除为可比较。