Яка різниця між методами додавання та пропозиції у черзі на Java?


109

Візьмемо PriorityQueueдля прикладу http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

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

На думку Collectiondoc, addметод часто намагатиметься забезпечити наявність елемента в межах, Collectionа не додавання дублікатів. Отже, моє запитання полягає в тому, яка різниця між методами addта offerметодами?

Це offerметод додасть дублікати незалежно? (Сумніваюсь, що це тому, що якщо у a Collectionмає бути лише чіткі елементи, це було б обійти).

EDIT: В і методи той же метод (див моя відповідь нижче). Чи може хтось надати мені приклад класу, де методи та методи відрізняються?PriorityQueueaddofferaddoffer

Відповіді:


148

Я думаю, різниця полягає в контракті, що коли елемент не можна додати до колекції, 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), який не може вставити елемент лише шляхом викидання виключення.


4
+1 за знахідкою , що фрагмент коду про те, коли використовувати offerпроти add.
Фінбарр

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методу?
Фінбарр

13

Різниця між offerі addпояснюється цими двома уривками з javadocs:

З Collectionінтерфейсу:

Якщо колекція відмовляється addпевному елементу з будь-якої причини, крім тієї, що він вже містить елемент, він повинен викинути виняток (а не повертати помилкове). Це зберігає інваріант, що колекція завжди містить вказаний елемент після повернення цього виклику.

З Queueінтерфейсу

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

PriorityQueueце Queueреалізація, яка не встановлює жодних обмежень щодо вставки. Тому addі offerметоди мають однакову семантику.

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


8

Різниця така:

  • метод пропозиції - намагається додати елемент до черги і повертає помилкове значення, якщо елемент не можна додати (як, у випадку, коли черга заповнений), або істинно, якщо елемент додано, і не кидає конкретного винятку .

  • метод add - намагається додати елемент до черги, повертає true, якщо елемент був доданий, або кидає IllegalStateException, якщо в даний момент немає місця.


1
метод add ніколи не повертає false, якщо елемент уже доступний Queue <String> q = новий PriorityQueue <> (); Рядок b = "java"; булева значення1 = q.add (b); boolean is2 = q.add ("java"); булева величина3 = q.add (b); boolean is4 = q.offer ("java"); булева величина5 = q.offer (b); булева величина6 = q.offer (b); System.out.println ("qq ::" + q);
Радж

Спасибі, Радж! Я оновив свою відповідь вище. Документація Oracle говорить: "Метод пропозиції, якщо це можливо, вставляє елемент, інакше повертає помилку. Це відрізняється від методу Collection.add, який не може додати елемент лише шляхом викидання неперевіреного винятку. Метод пропозиції призначений для використання при збої це нормальне, а не виняткове явище, наприклад, у черзі з фіксованою ємністю (або "обмеженою") ".
Максим Овсяніков

7

з вихідного коду в 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()відображення однакової поведінки.


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

Метод пропозиції, якщо можливо, вставляє елемент, інакше повертає помилку. Це відрізняється від методу Collection.add, який не може додати елемент лише шляхом викидання неперевіреного винятку. Метод пропозиції призначений для використання, коли вихід з ладу є звичайним, а не винятковою ситуацією, наприклад, у чергах з фіксованою ємністю (або "обмеженими").

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.