• 締切済み

イテレータと配列用のforの違いがよくわからない

イテレータと配列用のforの違いがよくわからないです。 本で勉強しているのですがその本の説明によると イテレータは「多数のオブジェクトを反復処理する基本」となるもの とかかれているのですが 具体的に使うとどう便利なのかがよくわからないです。 あと逆にもしイテレータがないとしたらどのように不便になるのでしょうか? 教えてください。よろしくおねがいします!

みんなの回答

回答No.1

イテレータそのものの存在意義について質問をしているのか、Java6から導入された拡張for文と従来型のイテレータを使った記述の使い分けについて質問をしているのかよくわからなかったので両方についてお答えします。 まず、前者についてお答えします。 イテレータはデータ構造の抽象化と効率を両立するために存在します。御存知の通り、Javaで使われるリスト構造には各要素が数珠つなぎになっているLinkedListと、配列を用いて実装されているArrayListがあり、前者は挿入削除を頻繁にする場合に強く、後者はその他全般の用途に強いです。そして、メソッドを実装をするときには効率を考えてどちらかを選びます。 このメソッドを使っているプログラムにはList型ということだけ伝えることで、後々の仕様変更によって効率の良さが変わった場合に自由にArrayListとLinkedListを変更することができます。 一般にArrayListはランダムにインデックスを指定してアクセスされるのには強いですが、LinkedListはインデックスを指定してアクセスすると最初の要素から順に辿らなくてはならないために効率が悪いです。そのため、今アクセスしている場所を覚えておく別のクラス(イテレータ)を用意して、それ経由でアクセスさせることで効率化を図ります。 例えば、次の例を考えます。 List<String> list = new LinkedList<String>(); 書く要素にアクセスするためにIteratorを使わない実装をあえてするとこうなります。 for (int index = 0; index < list.size(); index++) { System.out.println(list.get(index)); } これは、list.get(index)が呼ばれるたびにそのindexまで先頭からリストをたどるので効率が悪いです。 ここで、イテレータを使った実装だとこうなります。 Iterator<String> stringIterator = list.iterator(); while (stringIterator.hasNext()) { System.out.println(stringIterator.next()); } イテレータだと呼ばれるたびに次の要素を取り出すだけで最初からたぐるということをしないので圧倒的に効率が良いです。また、ArrayListの場合も今のindexを覚えていて、next()が呼ばれるたびにindexを1増やして値を返すだけなので効率が良いです。 そして、Listを使ったプログラムでは裏にLinkedListがあるのかArrayListがあるのかを考えずに効率の良いプログラムを書けます。 Java6から導入された拡張for文と従来型のイテレータを使った記述の使い分けについては、リストそのものを変更する操作が必要か否かで決めるとよいでしょう。 拡張for文を使うとイテレータを使った上でプログラムをかなりシンプルに記述できます。 for (String name : list) { System.out.println(name); } しかし、拡張for文ではリストそのものに変更を加える方法がないのである条件を満たした要素を削除するというプログラムを効率的に書けません。(あえてやるとしたら、for文をまわしながら別のリストを作ってそれともとのリストを置き換えることもできますが、メモリー効率もCPU効率も悪いです) この場合は下記のようにイテレータを使わざるを得ないでしょう。 Iterator<String> stringIterator = list.iterator(); while (stringIterator.hasNext()) { String name = stringIterator.next(); if (name.startsWith("test_")) { stringIterator.remove(); } } ...という説明でいかがでしょうか?

関連するQ&A