В чем разница между методами добавления и предложения в очереди в Java? - PullRequest
98 голосов
/ 24 апреля 2010

Возьмите 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 будет добавлять дубликаты независимо от? (Я сомневаюсь, что это потому, что если бы Collection имел только отдельные элементы, это могло бы обойти это).

EDIT: В PriorityQueue методы add и offer являются одним и тем же методом (см. Мой ответ ниже). Кто-нибудь может привести пример класса, где методы add и offer отличаются?

Ответы [ 8 ]

136 голосов
/ 24 апреля 2010

Я полагаю, что разница заключается в контракте: когда элемент не может быть добавлен в коллекцию, метод 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), который может потерпеть неудачу вставить элемент только бросив исключение.

24 голосов
/ 24 апреля 2010

Нет разницы для реализации 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");
}
12 голосов
/ 24 апреля 2010

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

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

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

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

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

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

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

6 голосов
/ 17 мая 2014

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

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

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

4 голосов
/ 25 февраля 2018

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

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

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

4 голосов
/ 11 июня 2014

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

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

2 голосов
/ 02 августа 2017

Я напишу пример кода 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 голосов
/ 07 мая 2013

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...