Реализация 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 ответ:
1) нельзя создать экземпляр массива универсального типа, не имея ссылки на класс объекта. Смотрите комментарий JavaDevil ниже для примера. Однако при создании массива объектов вместо этого нет необходимости передавать экземпляр класса в PriorityQueue.
2) PriorityQueue может сортировать свои элементы либо методом сопоставимого объектаE[] array = new E[10]; // won't compile
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); }