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
が別個の要素のみを持つべきである場合、それはそれを回避するからです)。
編集:PriorityQueue
では、add
メソッドとoffer
メソッドは同じメソッドです(以下の回答を参照)。 add
メソッドとoffer
メソッドが異なるクラスの例を教えてもらえますか?
違いはコントラクトにあると思います。要素をコレクションに追加できない場合、add
メソッドは例外をスローし、offer
はスローしません。
From: http://Java.Sun.com/j2se/1.5.0/docs/api/Java/util/Collection.html#add%28E%29
コレクションが要素を既に含んでいる以外の何らかの理由で特定の要素の追加を拒否した場合、コレクションはmust throw例外(falseを返すのではなく)。これにより、この呼び出しが返された後、コレクションが常に指定された要素を含むという不変条件が保持されます。
From: http://Java.Sun.com/j2se/1.5.0/docs/api/Java/util/Queue.html#offer%28E%29
可能な場合、指定された要素をこのキューに挿入します。挿入制限を課す可能性のあるキュー(容量の制限など)を使用する場合、例外をスローすることによってのみ要素の挿入に失敗する可能性のあるメソッドCollection.add(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からの次の2つの抜粋で説明されています。
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を返すが、失敗すると例外をスローすることが簡単にわかります。
違いは次のとおりです。
offerメソッド-キューへの要素の追加を試み、false if要素追加できません(キューがいっぱいの場合など)、またはtrue要素が追加された場合、および特定の例外をスローしません。
addメソッド-要素をキューに追加しようとし、trueが返された場合追加、または現在使用可能なスペースがない場合はIllegalStateExceptionをスローします。
Queue
インターフェイスは、add()
が現在使用可能なスペースがない場合(およびそうでない場合はIllegalStateException
を返す)、offer()
がtrue
をスローすることを指定します。容量制限のために要素を挿入できなかった場合は、false
を返します。
PriorityQueue
で同じである理由は、このキューが無制限に指定されているためです。つまり、容量の制限はありません。容量制限がない場合、add()
とoffer()
のコントラクトは同じ動作を表示します。
Java offerメソッドのコントラクトのサンプルコードを記述し、それらがどのように異なるかを示すメソッドを追加します。
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を返します。これは、未チェックの例外をスローすることによってのみ要素の追加に失敗する可能性があるCollection.addメソッドとは異なります。提供方法は、障害が例外的な発生ではなく通常の発生である場合、たとえば、固定容量(または「有界」)キューで使用されるように設計されています。