В чем разница между методами добавления и предложения в очереди на Java?
Возьмите PriorityQueue
, например http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)
Может ли кто-нибудь дать мне пример Queue
, где add
и offer
разные методы?
В соответствии с Collection
doc метод add
будет часто стремиться обеспечить, чтобы элемент существовал в Collection
скорее чем добавление дубликатов. Итак, мой вопрос: в чем разница между методами add
и offer
?
Может ли метод offer
добавлять дубликаты независимо? (Я сомневаюсь, что это связано с тем, что если Collection
должен иметь только отдельные элементы, это могло бы обойти это.)
EDIT:
В PriorityQueue
методы add
и offer
- это один и тот же метод (см. Мой ответ ниже). Может ли кто-нибудь дать мне пример класса, где методы add
и offer
отличаются?
Ответы
Ответ 1
Я предполагаю, что разница в контракте заключается в том, что, когда элемент не может быть добавлен в коллекцию, метод add
генерирует исключение, а offer
- нет.
От: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#add%28E%29
Если коллекция отказывается добавить конкретный элемент по любой причине кроме того, что он уже содержит элемент, он должен броситьисключение (а не возвращение ложный). Это сохраняет инвариант что коллекция всегда содержит указанный элемент после этого вызова возвращается.
От: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Queue.html#offer%28E%29
Вставляет указанный элемент в эта очередь, если это возможно. Когда используешь очереди, которые могут вводить вставку ограничения (например, емкость границы), предложение метода обычно предпочтительнее метода Collection.add(E), который может не вставьте элемент только путем исключение.
Ответ 2
Нет никакой разницы для реализации PriorityQueue.add
:
public boolean add(E e) {
return offer(e);
}
Для AbstractQueue
на самом деле есть разница:
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
Ответ 3
Разница между offer
и add
объясняется этими двумя выдержками из javadocs:
В интерфейсе Collection
:
Если коллекция отказывается от add
определенного элемента по какой-либо причине, кроме той, что она уже содержит элемент, она должна выдать исключение (а не возвращать false). Это сохраняет инвариант, что коллекция всегда содержит указанный элемент после вызова этого вызова.
От интерфейса Queue
При использовании очередей, которые могут вводить ограничения на вставку (например, ограничения пропускной способности), метод offer
обычно предпочтительнее метода Collection.add(E)
, который может не вставить элемент только путем исключения исключения.
PriorityQueue
- это реализация Queue
, которая не накладывает никаких ограничений на вставку. Поэтому методы add
и offer
имеют одинаковую семантику.
В отличие от этого, ArrayBlockingQueue
представляет собой реализацию, в которой offer
и add
ведут себя по-разному, в зависимости от того, как была создана очередь.
Ответ 4
из исходного кода в jdk 7 следующим образом:
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
мы можем легко узнать, что функция add вернет true, когда успешно добавит новый элемент в очередь, но выдает исключение при неудаче.
Ответ 5
Интерфейс Queue
указывает, что add()
будет бросать IllegalStateException
, если в настоящее время нет места (и в противном случае возвращать true
), а offer()
будет возвращать false
, если элемент не может быть вставлен из-за ограничений емкости.
Причина, по которой они одинаковы в PriorityQueue
, заключается в том, что указанная очередь задана как неограниченная, т.е. ограничений емкости нет. В случае ограничений пропускной способности контракты add()
и offer()
показывают одинаковое поведение.
Ответ 6
Источник: http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html
Метод предложения вставляет элемент, если это возможно, в противном случае возвращает false. Это отличается от метода Collection.add, который не может добавить элемент только путем исключения неконтролируемого исключения. Метод предложения предназначен для использования, когда отказ является обычным, а не исключительным случаем, например, в постоянных (или ограниченных) очередях.
Ответ 7
Я напишу код примера java-контракта для метода предложения и добавлю метод, показывающий, как они отличаются.
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
queue.add("TestQuue1");
queue.add("TestQuue2");
queue.add("TestQuue3"); // will throw "java.lang.IllegalStateException: Queue full
BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
queue.offer("TestQuue1");
queue.offer("TestQuue2");
queue.offer("TestQuue3"); // will not throw any exception