heap - Java PriorityQueue 实现 : Why Object[] queue instead of E[] queue? siftUp/siftDownComparable 中 "key"的用途是什么?

标签 heap java

我正在研究 JDK implementation of PriorityQueue .

1)整个队列存储在

 transient Object[] queue;

为什么不使用泛型 E 声明数组? (相反,有很多将 E 强制转换为类中的对象的操作。)

2) siftUpComparable/siftDownComparable 方法的第一行是

    Comparable<? super E> key = (Comparable<? super E>)x;

这是验证 x 是否可比较的保护子句吗? (否则为什么不直接使用x呢?)

这是整个方法:

private void siftDownComparable(int k, E x) {
    Comparable<? super E> key = (Comparable<? super E>)x;
    int half = size >>> 1;        // loop while a non-leaf
    while (k < half) {
        int child = (k << 1) + 1; // assume left child is least
        Object c = queue[child];
        int right = child + 1;
        if (right < size &&
            ((Comparable<? super E>) c).compareTo((E) queue[right]) > 0)
            c = queue[child = right];
        if (key.compareTo((E) c) <= 0)
            break;
        queue[k] = c;
        k = child;
    }
    queue[k] = key;
}

最佳答案

1) 如果没有对象类的引用,则无法实例化泛型类型的数组。请参阅下面 JavaDevil 的评论以获取示例。但是,通过创建对象数组,不需要将类的实例提供给 PriorityQueue。

E[] array = new E[10]; // won't compile

2) PriorityQueue 可以通过 Comparable 的对象 compareTo() 对其元素进行排序方法或对不一定是可比较的对象使用比较器。仅当创建 PriorityQueue 时未提供 Comparator 时,才会调用 siftDownComparable 方法。由于类型参数没有规定<E extends Comparable> ,您需要显式地转换它。这是 siftDown() 方法。

private void siftDown(int k, E x) {
    if (comparator != null)
        siftDownUsingComparator(k, x);
    else
        siftDownComparable(k, x);
}

关于heap - Java PriorityQueue 实现 : Why Object[] queue instead of E[] queue? siftUp/siftDownComparable 中 "key"的用途是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44448245/

相关文章:

java - Android SQLite - 尝试访问单行时出现 NullPointerException 但可以访问整个数据吗?

Python:为什么堆第一次弹出错误?

java - 使用 JFileChooser 将图像加载到 JLabel 图标中

python - 基于数组的 MinHeap

python - 从 Python heapq 中检索最小值

java - Android 游戏中不允许使用 W+E 加载段

java - 将缓存放在分布式 Redis 缓存的前面

java - 如何在一个 Maven 命令中执行多个目标,但每个目标有不同的参数

java - Hadoop上下文中Java的内存问题

c - 使用 Dijkstra 算法的有向图的优先级队列/最小堆