SunではIterator
、最後にアクセスしたコレクションの要素を削除するための remove メソッドが追加されました。コレクションに新しい要素を追加する add メソッドがないのはなぜですか? コレクションまたはイテレータにどのような副作用がありますか?
7 に答える
さて、ここに行きます:
答えは、設計に関するよくある質問に明確に記載されています。
Iterator.add メソッドを提供しないのはなぜですか?
Iterator の契約では反復の順序が保証されていないため、セマンティクスは不明です。ただし、反復の順序が保証されるため、ListIterator は追加操作を提供することに注意してください。
http://docs.oracle.com/javase/1.4.2/docs/guide/collections/designfaq.html#10
Iterator の唯一の目的は、コレクションを列挙することです。すべてのコレクションには、add()
目的に役立つメソッドが含まれています。コレクションは順序付けられる場合と順序付けられない場合があるため ( の場合)、 Iterator に追加しても意味がありませんHashSet
。
編集:Iterator
別の問題に取り組んでいるときに、方法がない別の理由を思いつきましたadd()
。ArrayList
(111 行目) と(149 行目) の内部を見るHashMap
と、実装がオブジェクトの配列を囲むいくつかのメソッドであることがわかります。次に、配列がメモリ内でどのように扱われるかを考えます。
これは 5 つの要素の配列です。ただし、インデックスは 6 つあります。この配列の文字 "a" は要素 0 としてリストされています。これは、コンピューターのように左から右に読み取るために、インデックス 0 から開始する必要があるためです。しかし、それは配列に要約されます)、インデックス 0 から開始し、インデックス 1 まで続けます。Iterator のこの時点で、 を呼び出しますadd("f");
。この時点で、 と の意味を比較してみましょadd()
うremove()
。remove()
は配列にスペースを残しますが、これは簡単に飛び越えることができます。なぜなら、それがメンバーではないことがすぐにわかるからです。一方で、add()
以前にはなかった新しい要素を追加します。これは、繰り返し処理する配列の長さに影響します。その最後の要素に到達するとどうなるでしょうか? それがそこにあること (つまり、配列が最大サイズを超えていないこと) を保証できますか?
全体として、いずれの引数にも有効なポイントがありますが、結論として、add()
メソッドの動作はすべての場合で明確に定義されているわけではありません。Sun は、機能を制限する場所を選択する必要があり、この方法を含めないことにしました。
リストで作業している場合は、追加操作と削除操作の両方を提供するListIteratorを使用できます。
イテレータは、次の要素へのポインタのみを持ちます。ここで、ListIterator には前の要素へのポインターもあります (逆方向にトラバースできることを思い出してください)。
add()
に含まれなかった理論的な理由は思いつきませんIterator
。Iterator
がそれ自体を介してコレクションから要素を削除できるように、追加された要素を同じ方法で処理するように設計できます。
しかし、私が Java でプログラミングを行ってきたすべての年数 (15 年以上) では、そう言えます。-- メソッドが欲しかったことは一度もありませんIterator.add()
。ですから、それほど有用ではないと思います。