Мне нужно создать очередь, в которой элементы будут добавлены и удалены в хронологическом порядке по умолчанию. Но если клиент устанавливает флаг приоритета для очереди, я должен иметь возможность вытягивать элементы на основе порядка приоритета элементов.java queue with dynamic priority flag
Я думаю о создании очереди приоритетов, поддерживаемой картой, которая отслеживает индекс очереди в порядке приоритета и на основе флага приоритета. Я могу вытащить элементы из карты и вытащить элемент из индекса из очереди.
Однако при таком подходе вопрос будет, погода я создаю карту по умолчанию или только если установлен флаг (учитывая, что стоимость создания карты на лету высока, я склонен к ее по умолчанию).
Пожалуйста, дайте мне знать, если есть лучший способ сделать это или существует существующая реализация.
Вот что я в настоящее время:
import javax.naming.OperationNotSupportedException;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class DynamicPriorityQueue<ComparableQueueElement> implements IQueue<ComparableQueueElement> {
private static final int CONSTANT_HUNDRED = 100;
private boolean fetchByCustomPriority = false;
private final ReentrantLock lock;
private final PriorityQueue<ComparableQueueElement> queue;
private final PriorityQueue<ComparableQueueElement> customPriorityQueue;
public DynamicPriorityQueue() {
this(null);
}
public DynamicPriorityQueue(Comparator<ComparableQueueElement> comparator) {
this.lock = new ReentrantLock();
this.queue = new PriorityQueue<>(CONSTANT_HUNDRED);
if (comparator != null)
this.customPriorityQueue = new PriorityQueue<ComparableQueueElement>(CONSTANT_HUNDRED, comparator);
else
this.customPriorityQueue = null;
}
public void setFetchByCustomPriority(boolean fetchByCustomPriority) throws OperationNotSupportedException {
if (this.customPriorityQueue == null)
throw new OperationNotSupportedException("Object was created without a custom comparator.");
this.fetchByCustomPriority = fetchByCustomPriority;
}
public void push(ComparableQueueElement t) throws InterruptedException {
if (this.lock.tryLock(CONSTANT_HUNDRED, TimeUnit.MILLISECONDS)) {
try {
this.queue.offer(t);
if (this.customPriorityQueue != null)
this.customPriorityQueue.offer(t);
} finally {
this.lock.unlock();
}
}
}
public ComparableQueueElement peek() {
return this.fetchByCustomPriority ? this.queue.peek()
: (this.customPriorityQueue != null ? this.customPriorityQueue.peek() : null);
}
public ComparableQueueElement pop() throws InterruptedException {
ComparableQueueElement returnElement = null;
if (this.lock.tryLock(CONSTANT_HUNDRED, TimeUnit.MILLISECONDS)) {
try {
if (this.fetchByCustomPriority && this.customPriorityQueue != null) {
returnElement = this.customPriorityQueue.poll();
this.queue.remove(returnElement);
}
else {
returnElement = this.queue.poll();
if (this.customPriorityQueue != null) {
this.customPriorityQueue.remove(returnElement);
}
}
} finally {
this.lock.unlock();
}
}
return returnElement;
}
}
поблагодарить вас efekctive. однако мой вопрос состоял в том, что дизайн будет оптимальным или я буду продолжать работу с другой структурой данных/подходом? – dissatisfiedprogrammer
Если все позиции в очереди приоритетов имеют одинаковый приоритет, то очередь push/pop должна быть очень эффективной в течение O (1). – ZhongYu
Вы запрашиваете контейнер, из которого потребитель может выбрать, следует ли удалить следующий элемент в порядке приоритета или, следующий элемент в порядке FIFO? –