Реализация Java PriorityQueue: почему Object [] queue вместо e [] queue? Какова цель "ключа" в siftUp/siftDownComparable?


Я изучаю реализацию JDK 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 2

1 ответ:

1) нельзя создать экземпляр массива универсального типа, не имея ссылки на класс объекта. Смотрите комментарий JavaDevil ниже для примера. Однако при создании массива объектов вместо этого нет необходимости передавать экземпляр класса в PriorityQueue.

E[] array = new E[10]; // won't compile
2) PriorityQueue может сортировать свои элементы либо методом сопоставимого объекта compareTo(), либо с помощью компаратора для объектов, которые не обязательно сопоставимы. Метод siftDownComparable вызывается только в том случае, если компаратор не был предоставлен при создании PriorityQueue. Поскольку параметр type не указывает, что <E extends Comparable>, необходимо привести его явно. Вот метод siftDown ().
private void siftDown(int k, E x) {
    if (comparator != null)
        siftDownUsingComparator(k, x);
    else
        siftDownComparable(k, x);
}