В чем разница между методами add и offer в очереди на Java?


взять 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 должны иметь только отдельные элементы, это позволит обойти это).

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

8 90

8 ответов:

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

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

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

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

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

нет никакой разницы для реализации 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");
}

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

С Collection интерфейс:

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

С Queue интерфейс

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

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

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

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

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

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

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

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

разница в следующем:

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

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

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

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

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