简体   繁体   English

泛型类中的Java泛型转换

[英]java generic casting in generic classes

I'm writing a simple implementation of a generic max heap. 我正在编写一个通用max堆的简单实现。 If I write 如果我写

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

it compiles. 它编译。 Now to actually implement the heap, ie write maxHeapify(), I need to be able to compare two T's. 现在要实际实现堆,即编写maxHeapify(),我需要能够比较两个T。 One option that a priori seems possible would be to tell the compiler that T implements Comparable. 先验似乎可行的一种选择是告诉编译器T实现Comparable。 But if I type replace < T > with < T implements Comparable > the compiler complains -- how can I do this? 但是,如果我用<T实现Comparable>来替换<T>,编译器会抱怨-我该怎么做?

Alternatively, I could define a class 另外,我可以定义一个类

public class HasValue{

  int value;

  public HasValue(int value){
        this.value = value;
  }

} }

and in theory I should then be able to compare two HasValue objects like x.value > y.value. 从理论上讲,我应该能够比较两个HasValue对象,例如x.value> y.value。 But if I type 但是如果我输入

public class FastMaxHeap<T extends HasValue>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

I now get a ClassCastException. 我现在得到一个ClassCastException。 What is going on here? 这里发生了什么? Java generics hurt my brain. Java泛型伤害了我的大脑。

In the first case T extends Object which is erased to Object at runtime. 在第一种情况下, T extends Object ,该Object在运行时被擦除为Object

In the second case T extends HasValue is erased to HasValue so you need to have. 在第二种情况下, T extends HasValue擦除为HasValue因此您需要拥有。

data = (T[]) new HasValue[HEAP_SIZE];

IMHO It is needlessly pedantic that Java doesn't allow new T[HEAP_SIZE] to do what you have to do anyway. 恕我直言,Java不允许new T[HEAP_SIZE]来做您必须做的事情,这是不必要的。

You may try this one (not compiled, yet) 您可以尝试这一步(尚未编译)

public class FastMaxHeap<T extends HasValue>{

  HasValue[] data;
  int size;

  static final int HEAP_SIZE = 10000;

   public FastMaxHeap(){
     data = new HasValue[HEAP_SIZE];
     size = 0;
   }
}

It is better to have type token to create arrays like this 最好有类型标记来创建这样的数组

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(Class<T> clazz){
    data = (T[])Array.newInstance(clazz, HEAP_SIZE);
    size = 0;
  }
}

In such way you will have no ClassCastExceptions in runtime 这样,您将在运行时没有ClassCastExceptions

And also: < T implements Comparable > is not correct, correct one is < T extends Comparable > 而且: < T implements Comparable >不正确,正确的是< T extends Comparable >

Your heap should accept a Comparator< T > as a constructor argument. 您的堆应接受Comparator <T>作为构造函数参数。 Problem solved. 问题解决了。 Client can use any type he wants. 客户可以使用他想要的任何类型。 You can also supply a simple overload which infers the comparator implementation for types T that already implement Comparable. 您还可以提供一个简单的重载,它推断已经实现Comparable的T类型的比较器实现。

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

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