Qual é a diferença entre os métodos add e offer em uma Queue em Java?

109

Veja, PriorityQueuepor exemplo, http://java.sun.com/j2se/1.5.0/docs/api/java/util/PriorityQueue.html#offer(E)

Alguém pode me dar um exemplo de Queueonde os métodos adde offersão diferentes?

De acordo com o Collectiondoc, o addmétodo frequentemente buscará garantir que um elemento exista no em Collectionvez de adicionar duplicatas. Portanto, minha pergunta é: qual é a diferença entre os métodos adde offer?

O offermétodo adicionará duplicatas independentemente? (Duvido que seja porque se a Collectiontivesse apenas elementos distintos, isso contornaria isso).

EDIT: Em um PriorityQueueos métodos adde offersão o mesmo método (veja minha resposta abaixo). Alguém pode me dar um exemplo de classe onde os métodos adde offersão diferentes?

Finbarr
fonte

Respostas:

148

Acho que a diferença está no contrato, que quando o elemento não pode ser adicionado à coleção, o addmétodo lança uma exceção e offernão o faz.

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

Se uma coleção se recusar a adicionar um elemento específico por qualquer motivo diferente de que já contém o elemento, ela deve lançar uma exceção (em vez de retornar false). Isso preserva a invariável de que uma coleção sempre contém o elemento especificado após o retorno dessa chamada.

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

Insere o elemento especificado nesta fila, se possível. Ao usar filas que podem impor restrições de inserção (por exemplo, limites de capacidade), a oferta do método geralmente é preferível ao método Collection.add (E), que pode falhar ao inserir um elemento apenas lançando uma exceção.

DVD
fonte
4
+1 para constatação de que trecho sobre quando usar offervs add.
Finbarr
28

Não há diferença para a implementação de PriorityQueue.add:

public boolean add(E e) {
    return offer(e);
}

Pois AbstractQueuerealmente há uma diferença:

public boolean add(E e) {
    if (offer(e))
        return true;
    else
        throw new IllegalStateException("Queue full");
}
Peter Lang
fonte
Eu sei, acabei de postar essa resposta há alguns minutos. Você conhece alguma classe em que o addmétodo seja diferente do offermétodo?
Finbarr
13

A diferença entre offere addé explicada por estes dois trechos dos javadocs:

Na Collectioninterface:

Se uma coleção se recusar a addum elemento específico por qualquer motivo diferente de que já contém o elemento, ela deve lançar uma exceção (em vez de retornar falso). Isso preserva a invariável de que uma coleção sempre contém o elemento especificado após o retorno dessa chamada.

Da Queueinterface

Ao usar filas que podem impor restrições de inserção (por exemplo, limites de capacidade), o método offergeralmente é preferível ao método Collection.add(E), que pode falhar ao inserir um elemento apenas lançando uma exceção.

PriorityQueueé uma Queueimplementação que não impõe nenhuma restrição de inserção. Portanto, os métodos adde offertêm a mesma semântica.

Por outro lado, ArrayBlockingQueueé uma implementação na qual offere addse comporta de maneira diferente, dependendo de como a fila foi instanciada.

Stephen C
fonte
8

A diferença é a seguinte:

  • método de oferta - tenta adicionar um elemento a uma fila e retorna falso se o elemento não puder ser adicionado (como no caso de uma fila cheia), ou verdadeiro se o elemento foi adicionado, e não lança nenhuma exceção específica .

  • add method - tenta adicionar um elemento a uma fila, retorna true se o elemento foi adicionado ou lança uma IllegalStateException se nenhum espaço estiver disponível no momento.

Maksym Ovsianikov
fonte
1
o método add nunca retorna falso se o elemento já estiver disponível Queue <String> q = new PriorityQueue <> (); String b = "java"; booleano is1 = q.add (b); boolean is2 = q.add ("java"); booleano is3 = q.add (b); boolean is4 = q.offer ("java"); booleano is5 = q.offer (b); boolean is6 = q.offer (b); System.out.println ("qq ::" + q);
Raj
Obrigado, Raj! Eu atualizei minha resposta acima. A documentação do Oracle diz: "O método de oferta insere um elemento se possível, caso contrário, retorna falso. Isso difere do método Collection.add, que pode falhar ao adicionar um elemento apenas lançando uma exceção não verificada. O método de oferta é projetado para uso em caso de falha é uma ocorrência normal, em vez de excepcional, por exemplo, em filas de capacidade fixa (ou "limitadas"). "
Maksym Ovsianikov
7

do código-fonte em jdk 7 da seguinte forma:

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

podemos saber facilmente que a função add retornará true quando adicionar com sucesso um novo elemento na fila, mas lançará uma exceção quando falhar.

Heavin
fonte
5

A Queueinterface especifica que add()lançará um IllegalStateExceptionse nenhum espaço estiver disponível no momento (e caso contrário, retornará true) enquanto offer()retornaráfalse se o elemento não puder ser inserido devido a restrições de capacidade.

A razão pela qual eles são iguais em a PriorityQueueé que essa fila é especificada para ser ilimitada, ou seja, não há restrições de capacidade. No caso de não haver restrições de capacidade, os contratos de add()e offer()apresentam o mesmo comportamento.

Peter
fonte
2

Escreverei o código de exemplo do contrato java para o método de oferta e adicionarei o método mostrando como eles diferem.

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
Aslam anwer
fonte
0

Fonte: http://docs.oracle.com/javase/6/docs/api/java/util/Queue.html

O método de oferta insere um elemento se possível, caso contrário, retorna false. Isso difere do método Collection.add, que pode falhar ao adicionar um elemento apenas lançando uma exceção não verificada. O método de oferta é projetado para uso quando a falha é normal, ao invés de uma ocorrência excepcional, por exemplo, em filas de capacidade fixa (ou "limitadas").

Yeshodhan Kulkarni
fonte