В чем разница между методами добавления и предложения в очереди в Java?


109

Возьмем, PriorityQueueнапример, http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

Может кто - нибудь дать мне пример , Queueгде addи offerметоды различны?

Согласно Collectionдокументу, addметод часто стремится обеспечить наличие элемента внутри, Collectionа не добавлять дубликаты. Так что мой вопрос, в чем разница между addи offerметодами?

Неужели offerметод все равно добавит дубликаты? (Я сомневаюсь, что это потому, что если бы у a Collectionбыли только отдельные элементы, это бы обошло это).

РЕДАКТИРОВАТЬ: PriorityQueueв методах addи offerиспользуется один и тот же метод (см. Мой ответ ниже). Может кто - нибудь дать мне пример класса , где addи offerметоды различны?

Ответы:


148

Я предполагаю, что разница заключается в контракте: когда элемент не может быть добавлен в коллекцию, addметод выдает исключение и offerне делает.

От: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html#add%28E%29

Если коллекция отказывается добавить определенный элемент по любой причине, кроме той, что она уже содержит элемент, она должна вызвать исключение (вместо того, чтобы возвращать false). Это сохраняет инвариант, что коллекция всегда содержит указанный элемент после возврата из этого вызова.

От: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Queue.html#offer%28E%29

Если возможно, вставляет указанный элемент в эту очередь. При использовании очередей, которые могут налагать ограничения на вставку (например, границы емкости), предложение метода обычно предпочтительнее, чем метод Collection.add (E), который может не вставить элемент только в результате генерации исключения.


4
+1 за находкой , что фрагмент кода о том, когда использовать offerпротив add.
Finbarr

28

Нет разницы по реализации 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");
}

Я знаю, я сам опубликовал этот ответ несколько минут назад. Вы знаете какие-либо классы, в которых addметод отличается от offerметода?
Finbarr

13

Разница между offerи addобъясняется этими двумя отрывками из документации javadoc:

Из Collectionинтерфейса:

Если коллекция отказывается от addконкретного элемента по какой-либо причине, кроме той, что она уже содержит элемент, она должна вызвать исключение (а не вернуть false). Это сохраняет инвариант, что коллекция всегда содержит указанный элемент после возврата из этого вызова.

Из Queueинтерфейса

При использовании очередей, которые могут налагать ограничения на вставку (например, границы емкости), метод offerобычно предпочтительнее Collection.add(E), чем метод , который может не вставить элемент только в результате генерации исключения.

PriorityQueueэто Queueреализация, которая не накладывает никаких ограничений на вставку. Поэтому addи offerметоды имеют ту же семантику.

Напротив, ArrayBlockingQueueэто реализация, в которой offerи addведут себя по-разному, в зависимости от того, как была создана очередь.


8

Разница следующая:

  • метод предложения - пытается добавить элемент в очередь и возвращает false, если элемент не может быть добавлен (например, в случае, когда очередь заполнена), или true, если элемент был добавлен, и не вызывает какого-либо конкретного исключения .

  • add method - пытается добавить элемент в очередь, возвращает true, если элемент был добавлен, или выдает исключение IllegalStateException, если в данный момент нет свободного места.


1
Метод add никогда не возвращает false, если элемент уже доступен Queue <String> q = new PriorityQueue <> (); Строка b = "java"; логическое is1 = q.add (b); логическое is2 = q.add ("java"); логическое is3 = q.add (b); логическое is4 = q.offer ("java"); логическое is5 = q.offer (b); логическое is6 = q.offer (b); System.out.println ("qq ::" + q);
Raj

Спасибо, Радж! Я обновил свой ответ выше. В документации Oracle говорится: «Метод предложения вставляет элемент, если это возможно, в противном случае возвращается false. Это отличается от метода Collection.add, который может не добавить элемент, только выбрасывая непроверенное исключение. Метод предложения предназначен для использования в случае сбоя. является нормальным, а не исключительным случаем, например, в очередях фиксированной емкости (или «ограниченных») ».
Максим Овсяников

7

из исходного кода в jdk 7 следующим образом:

public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("Queue full");
}

мы можем легко узнать, что функция добавления вернет true при успешном добавлении нового элемента в очередь, но выдаст исключение при неудаче.


6

В Queueинтерфейсе определяет , что add()будет сгенерирован , IllegalStateExceptionесли нет места в настоящее время доступно (и в противном случае возврат true) , а offer()вернется , falseесли элемент не может быть введен из - за ограничения пропускной способности.

Причина, по которой они одинаковы в a, PriorityQueueзаключается в том, что эта очередь указана как неограниченная, т. Е. Нет ограничений по емкости. В случае отсутствия ограничений мощности контракты add()и offer()демонстрируют одинаковое поведение.


2

Я напишу пример кода 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

0

Источник: http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html

Метод предложения вставляет элемент, если это возможно, иначе возвращает false. Это отличается от метода Collection.add, который может не добавить элемент, только вызвав непроверенное исключение. Метод предложения разработан для использования, когда сбой является нормальным, а не исключительным случаем, например, в очередях с фиксированной емкостью (или «ограниченной»).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.