- - PR -
Iteratorについて
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2003-10-15 13:49
Iterator を使用する場合のメリット/ディメリットは、何があるんでしょうか?
(どのような場合には、Iteratorを使用して、 どのような場合は、使用しない方がよいっといった指針のような物はあるんでしょうか?) ## 例えば、Listを要素数分ループさせる場合に、 ## Iteratorでもループできますし、size()でもループできると思います。 ArrayList list = new ArrayList(); Iterator i = list.iterator(); while (i.hasNext()) { } for (int i=0; i<list.size(); i++) { } | ||||
|
投稿日時: 2003-10-15 13:57
ここを読んでみてください。http://www.dmz.hitachi-sk.co.jp/Java/Tech/pattern/gof/iterator.html | ||||
|
投稿日時: 2003-10-15 14:02
swatです。
Iteratorのばあい、iterator生成時点でのリストのすべての要素への順次アクセスが出来ることを保証してくれていたような気がします。 自分でforでまわした場合、すべての要素に順次アクセスできるかどうかはコーディング次第ですので、必ずすべての要素にアクセスしたい、というのなら、Iterator、ということかもしれません。 それと、Map系のコレクションクラスの順次アクセスにはiteratorが便利ですね。 #私も厳密にはわかっていません。識者のフォローを期待します。 [ メッセージ編集済み 編集者: swat 編集日時 2003-10-15 14:02 ] | ||||
|
投稿日時: 2003-10-15 14:13
対象によって変えるってのがいいのではないでしょうか?
ArrayListやVectorの場合はsize()+get(n) それ以外はIterator メソッド内だけで完結するのであれば、ロジックにあわせて クラスを選べばいいかと。 | ||||
|
投稿日時: 2003-10-15 14:37
Iteratorの場合は、もしイテレート中に、Iteratorを取り出したCollectionやMapの内容に変更があった場合には、ConcurrentModificationExceptionがスローされます。
それに対して、カウンタでぐるぐる回す方法だと、内容に変更があってもConcurrentModificationExceptionはスローされません。 つまり、Iteratorの場合は、Iteratorを取り出した時点でその内容が確定します。 ※ 上記の話は、CollectionやMapの実装にArrayListやHashMap(CoreAPIのクラス)を使用した場合の話です。 カスタム実装を使用した場合は必ずしも上記の通りではありません。 | ||||
|
投稿日時: 2003-10-15 14:49
皆さんご返信ありがとうございます。
私の場合、内部構造を隠蔽したい場合(ユーティリティー等)は、Iterator を 使用し、その他は、size()+ get(n) を使用していましが、 本当はどう違うんだろうという疑問がわき投稿しました。 ※Map系の場合は、順次アクセスする事は稀なんで、Listまで変換していました swat様の言う通り、Map系のコレクションクラスの順次アクセスには iteratorを使用した方がよさそうですね。 で、結論はこんな感じでしょうか? デザインパターンでは、Iteratorを使用すべきだと思いますが、 パフォーマンスが若干悪い・コーディングが面倒等々の理由があるので 以下の3点を念頭に、後は、ケースBYケース にする。 1.内部構造を隠蔽したい場合は、Iterator 2.Listを使用する場合は、size()+ get(n) 3.Map系の、順次アクセスする場合は、Iterator 間違っていれば、ご指摘して下さい。 | ||||
|
投稿日時: 2003-10-15 15:00
こんにちは、さくらばです。
2. は問題ありです。というのも LinkedList の get(n) はむちゃくちゃ遅いのですが、 Iterator を使用した場合はとても速くアクセスできます。 その代わりに次のようなルールがいいと思います。 Collection インタフェースをインプリメントしているクラスのうち 1. java.util.RandomAccess インタフェースをインプリメントしているものは get(n) 2. RandomAccess インタフェースをインプリメントしていないものは Iterator を使用する 1. の条件に合うのは ArrayList, Vector 2. の方は LinkedList, HashSet, LinkedHashSet などです。 | ||||
|
投稿日時: 2003-10-15 15:16
Iteratorを使用する場合は、「コレクションの全要素に対して順次アクセスする」という意図がソースを見るだけで伝わるというメリットがあるのではないでしょうか。
それに対して、カウンタを使用する方法だと、コメントが必要になる場合もあります。 なので、僕の場合はできる限りIteratorを使用しています。 ただし、さくらばさんが指摘する通り、コレクションの特性や要素数によっては性能の差が顕著になるので、場面にあわせた使いわけが必要になることもあります。 でも、そんな場面は頻繁には出てこないと思っています。
[ メッセージ編集済み 編集者: Emacs信者 編集日時 2003-10-15 15:17 ] | ||||
