- PR -

Listから順に値を取得する方法

1
投稿者投稿内容
Oz
会議室デビュー日: 2006/12/14
投稿数: 15
投稿日時: 2007-05-12 01:06
いつも大変お世話になっております。

List listHoge = new ArrayList();

for(int i=0 ; i<5 ; i++){
 HogeBean bean = new HogeBean();
 bean.setHoge("テスト"+i);
 listHoge.add(bean);
}

このようなListに入れた値を順に取得する場合、
(HogeBeanは変数hogeとそのgetter/setterを持つクラス)

//@Listを回す。
for(int i=0 ; i<listHoge.size() ; i++){
 HogeBean bean = (HogeBean)listHoge.get(i);
 System.out.println(bean.getHoge());
}

//AIteratorにして回す。
Iterator itrHoge = listHoge.iterator();
while(itrHoge.hasNext()){
 HogeBean bean = (HogeBean)itrHoge.next();
 System.out.println(bean.getHoge());
}

//B配列にして回す。
Object[] hogeArray = listHoge.toArray();
for(int i=0 ; i<hogeArray.length ; i++){
 HogeBean bean = (HogeBean)hogeArray[i];
 System.out.println(bean.getHoge());
}

という方法が考えられると思うのですが、
これらに違いはあるのでしょうか?
一応、試してみたところどの方法でも
テスト0〜4まで出力できましたが、
具体的に@〜Bのうちこれを使うべきである、
またはこのような場合にはこれを使ったほうがいい、
これを使うのが一番処理が速く済む、
どれも変わらないがスタンダードなやり方はこれである、
逆にこの方法は問題があるので使うべきではない、などあるのでしょうか?
また、この3通り以外のもっといい方法はあるのでしょうか?

何卒、ご教授のほどよろしくお願いいたします。
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2007-05-12 01:35
どれでもいいと思います。Java5以降であればこんな書き方も出来ます。
コード:
    List<HogeBean> listHoge = new ArrayList<HogeBean>();
    for(int i=0 ; i<5 ; i++){
      HogeBean bean = new HogeBean();
      bean.setHoge("テスト"+i);
      listHoge.add(bean);
    }
    
    for(HogeBean hogeBean: listHoge){
      System.out.println(hogeBean.getHoge());
    }




また、配列にするときは以下のようにするとキャスト回数が減ります。
HogeBean[] hogeBeans = (HogeBean[])listHoge.toArray(new HogeBean[listHoge.size()]);
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2007-05-12 01:35
(3)は、配列のコピーが無駄に発生するので、明らかに非効率的。

ArrayListなら、(2)より(1)の方が(無視できるほど軽微な差だが)効率良いかも。
LinkedListの場合は、(1)よりも(2)の方が遥かに効率的。

ま、「どうやって列挙するのが効率的かは、そのListが知っている」ということで、
(2)のように書くのがオブジェクト指向的には正しいのだろう。

Java5以降なら、

List<HogeBean> listHoge = new ArrayList<HogeBean>();
...
for( HogeBean bean : listHoge ){
System.out.println(bean.getHoge());
}

と書いて、後はコンパイラに任せるのが一番良いと思うが。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-05-12 13:10
後輩に教える際に考察したことがあったのでそのときの話を。

昔ながらのfor文はインデックスを利用することが前提。
つまり、

コード:
Object[] array;
for (int i=0; i<array.length; i++) {
  // ループ内でiを使う
  System.out.println(array[i]);
}

// Listの場合
List list;
for (int i=0; i<list.size(); i++) {
  Object o = list.get(i);
  System.out.println(o);
}



というのが基本的な形式で、配列やjava.util.Listなどの
インデックスでアクセスできる場合のみ利用できた。
ところが、Java5 からはいわゆるfor-each構文がサポートされたので
順番にアクセスするだけなら配列もjava.util.Listもjava.util.Iteratorも
すべて同等に扱えるようになった。

コード:
Object[] array;
for (Object o : array) {
  System.out.println(o);
}

List list;
for (Object o : list) {
  System.out.println(o);
}

Iterator ite;
for (Object o : ite) {
  System.out.println(o);
}



というわけで、for-eachのほうが抽象度が高く、統一的に扱えるので
普段はfor-eachを使ったほうがよいのだろう、という話。

ただし、どうしてもインデックスを使わないといけない場合もあって、
たとえば長さの同じ二つの配列を利用する場合とか、
単にループカウンタiの値が使いたい場合など。
初心者はfor-eachしか知らなくてもいいのかもしれない。
Oz
会議室デビュー日: 2006/12/14
投稿数: 15
投稿日時: 2007-05-13 10:39
インギさん・coasmさん・nagiseさん、レスありがとうございました。

for-each構文については一応知っていたのですが、
現在の開発環境がJava1.4なので今回は考えから外していました。
(親記事に書いておくべきでした、すいません)

ですが、for-eachが推奨されるということも分かりましたので
今後の開発の参考にしたいと思います。

例コードがあまり適当でなかったようで、
実際はBeanをつめたListを返すメソッドを呼んで、
そこから値を取り出すコードを組んでいるときに親記事のような疑問にぶつかったので、
今回はAの方法を使いたいと思います。

ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)