泛型数组无法进行比较

来源:8-2 堆的基础表示

qq_萌新_4

2020-06-13

尝试用数组构造线性的优先队列

public Array(int capacity) {
            data = (E[]) new Object[capacity];
            size = 0;
        }

这里必须将Array和ArrayPriorityQueue都统一为泛型E的类型,否则报错:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
	at ArrayPriorityQueue$Array.<init>(ArrayPriorityQueue.java:10)
	at ArrayPriorityQueue.<init>(ArrayPriorityQueue.java:72)
	at ArrayPriorityQueue.<init>(ArrayPriorityQueue.java:77)
	at ArrayPriorityQueue.main(ArrayPriorityQueue.java:136)

但是统一泛型后,arr的get(index)方法在进行比较时提示必须进行强制类型转换,这里编译器将返回值识别为了Object类型:

图片描述
然而我get函数返回值明明是E类型:

 public E get(int index) {
            if (index < 0 || index >= size) {
                throw new IllegalArgumentException("Get failed. Index is illegal.");
            }
            return data[index];
        }

虽然结果能出来,但是有点想不通,请老师指教
图片描述

还有就是泛型表示为ArrayPriorityQueue<E extends Comparable<? super E>>是否会更好?百度了一下,Comparable<? super E>Comparable<? extends E>两者的区别好像说的不是很清楚,我看java API大量使用这种表达方式,老师能否指导一下?谢谢啦

PS:数组构造优先队列,出队操作设置为O(1),那么入队的时候就要像我这样进行数据比较;入队操作为O(1)那么意味着队列的顺序就是乱的,那么出队操作就需要进行扫描,时间复杂度为O(n)。相较来说,入队操作进行比较,最终显示结果比较直观一点。

写回答

1回答

liuyubobobo

2020-06-15

1

具体还需要再看源码确认一下,但是整体,我估计你遇到的问题涉及到 Java 的泛型机制问题。简单来说,Java 中的泛型机制是“假”的泛型机制,是在运行时才真的确定类型,而非编译时。因此,在编译时,你的情况里,编译器可能暂时只知道这是一个 Object,而不是一个 E。


2

<? super E> 和 <? extends E> 的区别是: 一个是 E 的某个父类型;一个是 E 的某个子类型。


具体这二者在标准库中的应用,解释起来太复杂了,也不是这个课程的内容了,有兴趣可以参考这里:https://stackoverflow.com/questions/1368166/what-is-a-difference-between-super-e-and-extends-e/1368245


这个课程的代码中,使用 ArrayPriorityQueue<E extends Comparable<E>> 应该就是可以的。


3

PS 的内容没毛病:)


继续加油!:)

0
1
qq_萌新_4
原来java泛型只是运行时才起作用,学到了
2020-06-15
共1条回复

玩转数据结构

动态数组/栈/队列/链表/BST/堆/线段树/Trie/并查集/AVL/红黑树…

6221 学习 · 1704 问题

查看课程