В чем разница между методами добавления и предложения в очереди на 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