Как получить PriorityQueue
сортировку по тому, что я хочу отсортировать?
источник
Как получить PriorityQueue
сортировку по тому, что я хочу отсортировать?
Используйте перегрузку конструктора, которая принимает Comparator<? super E> comparator
и передает компаратор, который сравнивается соответствующим образом для вашего порядка сортировки. Если вы приведете пример того, как вы хотите сортировать, мы можем предоставить пример кода для реализации компаратора, если вы не уверены. (Это довольно просто, хотя.)
Как было сказано в другом месте: offer
и add
это просто разные реализации метода интерфейса. В источнике JDK, который я получил, add
звонит offer
. Хотя add
и offer
имеет потенциально различное поведение в общих из - за способности к , offer
чтобы указать , что значение не может быть добавлено из - за ограничения по размеру, эта разница не имеет значения , в PriorityQueue
котором не ограниченно.
Вот пример сортировки очереди по длине строки:
// Test.java
import java.util.Comparator;
import java.util.PriorityQueue;
public class Test {
public static void main(String[] args) {
Comparator<String> comparator = new StringLengthComparator();
PriorityQueue<String> queue = new PriorityQueue<String>(10, comparator);
queue.add("short");
queue.add("very long indeed");
queue.add("medium");
while (queue.size() != 0) {
System.out.println(queue.remove());
}
}
}
// StringLengthComparator.java
import java.util.Comparator;
public class StringLengthComparator implements Comparator<String> {
@Override
public int compare(String x, String y) {
// Assume neither string is null. Real code should
// probably be more robust
// You could also just return x.length() - y.length(),
// which would be more efficient.
if (x.length() < y.length()) {
return -1;
}
if (x.length() > y.length()) {
return 1;
}
return 0;
}
}
Вот вывод:
короткая
средний
очень долго
compare
реализация не должна быть простоreturn x.length() - y.length()
? (Предотвращение ветвления прогноза)add()
для операции добавления, тоremove()
чувствует себя разумно; если бы я использовал,offer()
я бы, вероятно, использовалpoll()
... но это просто личное предпочтение.Решение Java 8
Мы можем использовать
lambda expression
илиmethod reference
внедрить в Java 8. Если у нас есть некоторые значения String, хранящиеся в очереди приоритетов (с емкостью 5), мы можем предоставить встроенный компаратор (на основе длины String):Использование лямбда-выражения
Использование метода Reference
Тогда мы можем использовать любой из них как:
Это напечатает:
Чтобы изменить порядок (изменить его на очередь с максимальным приоритетом), просто измените порядок в встроенном компараторе или используйте
reversed
как:Мы также можем использовать
Collections.reverseOrder
:Таким образом, мы можем видеть, что
Collections.reverseOrder
перегружен, чтобы взять компаратор, который может быть полезен для пользовательских объектов. Наreversed
самом деле используетCollections.reverseOrder
:предложение () против добавления ()
Согласно документу
При использовании очереди с ограниченной емкостью, предложение (), как правило, предпочтительнее, чем add (), который может не вставить элемент, только вызвав исключение. И PriorityQueue - это очередь с неограниченным приоритетом, основанная на куче приоритетов.
источник
5
указывает начальную емкость очереди?Просто пройти соответствующую
Comparator
к конструктору :Единственная разница между
offer
иadd
является интерфейсом, к которому они принадлежат.offer
принадлежитQueue<E>
, тогдаadd
как изначально видно вCollection<E>
интерфейсе. Кроме того, оба метода делают одно и то же - вставляют указанный элемент в очередь с приоритетами.источник
из API очереди :
источник
ничем не отличается, как заявляют в Javadoc:
источник
Просто, чтобы ответить на вопрос
add()
противoffer()
(так как другой отлично ответил imo, а это может и не быть):Согласно JavaDoc для интерфейса Queue : «Метод offer вставляет элемент, если это возможно, в противном случае возвращает false. Это отличается от метода Collection.add, который может не добавить элемент только путем генерирования непроверенного исключения. Метод offer предназначен для использовать, когда сбой является нормальным, а не исключительным случаем, например, в очередях с фиксированной (или «ограниченной») емкостью ».
Это означает, что если вы можете добавить элемент (который всегда должен иметь место в PriorityQueue), они работают точно так же. Но если вы не можете добавить элемент,
offer()
вы получите приятное и симпатичноеfalse
возвращение, в то время как создастadd()
неприятное непроверенное исключение, которое вам не нужно в вашем коде. Если неудача при добавлении означает, что код работает должным образом и / или это то, что вы обычно проверяете, используйтеoffer()
. Если ошибка добавления означает, что что-то сломано, используйтеadd()
и обработайте полученное исключение в соответствии со спецификациями интерфейса Collection .Они оба реализованы таким образом, чтобы полностью заполнить контракт в интерфейсе очереди, в котором указаны
offer()
сбои, путем возвратаfalse
( предпочтительный метод в очередях с ограниченной емкостью ), а также поддерживать контракт на интерфейсе коллекции, который всегда указывает наadd()
сбои, вызывая исключение .Во всяком случае, надеюсь, что проясняет хотя бы эту часть вопроса.
источник
Здесь мы можем определить пользовательский компаратор:
Разница между предложением и методами добавления: ссылка
источник
Передайте это
Comparator
. Заполните желаемый тип вместоT
Использование лямбды (Java 8+):
Классический способ, используя анонимный класс:
Чтобы отсортировать в обратном порядке, просто поменяйте местами e1, e2.
источник
Мне также было интересно узнать о порядке печати. Рассмотрим этот случай, например:
Для очереди с приоритетами:
Этот код:
может печатать иначе, чем:
Я нашел ответ из обсуждения на другом форуме , где пользователь сказал: «методы offer () / add () только вставляют элемент в очередь. Если вы хотите предсказуемый порядок, вы должны использовать peek / poll, который возвращает заголовок». из очереди. "
источник
В качестве альтернативы использованию
Comparator
вы также можете использовать класс, который вы используете, в своемPriorityQueue
инструментеComparable
(и, соответственно, переопределитьcompareTo
метод).Обратите внимание, что обычно лучше использовать только
Comparable
вместо того,Comparator
если это упорядочение является интуитивным упорядочением объекта - если, например, у вас есть сценарий использования для сортировкиPerson
объектов по возрасту, вероятно, лучше всего использоватьComparator
вместо этого.Вывод:
источник
Очередь приоритетов имеет некоторый приоритет, назначенный каждому элементу. Элемент с наивысшим приоритетом появляется в верхней части очереди. Теперь это зависит от вас, как вы хотите, чтобы приоритет был назначен каждому из элементов. Если вы этого не сделаете, Java сделает это по умолчанию. Элементу с наименьшим значением присваивается наивысший приоритет, и поэтому он сначала удаляется из очереди. Если есть несколько элементов с одинаковым наивысшим приоритетом, связь нарушается произвольно. Вы также можете указать порядок с помощью Comparator в конструкторе
PriorityQueue(initialCapacity, comparator)
Пример кода:
Вывод:
Иначе, Вы также можете определить Custom Comparator:
источник
Вот простой пример, который вы можете использовать для начального обучения:
источник