Entry

プログラミング・メモ - それでも基本 for ループは使うんだろうな……

2007年10月29日

おそらく,こゆのは一般論としてあれこれ言うもんじゃなくて,具体的な実装との関係であれこれするもんだと思うんですけれど,こちらの話から。

もちろん櫻庭さんのいうようにArrayListのIterator(および拡張forループ)と基本forループのgetとを比較すると、getの方が若干速いのは事実なんです。いろんなところで測定されています。そういう主旨での記述だと思いますが、でもこれはIteratorの存在意義を無視してると思いますよ。Iteratorはどんな実装でも最適な方法でループするためにあるんですから。

Iteratorより基本forループでArrayListのget()を使ったほうがいいなんて話はもはや百害あって一利なしです。 - 矢野勉のはてな日記

例えば,こういう場合。

import java.util.List;
import java.util.ArrayList;

class Sample
{
    public static void main(String args[]) {
        List<String> lowerArrayList = new ArrayList<String>();
        List<String> upperArrayList = new ArrayList<String>();

        lowerArrayList.add("foo");
        lowerArrayList.add("bar");
        lowerArrayList.add("baz");

        upperArrayList.add("FOO");
        upperArrayList.add("BAR");
        upperArrayList.add("BAZ");

        String lower = null;
        String upper = null;
        int max = (lowerArrayList.size() > upperArrayList.size()) ?
            upperArrayList.size() :
            lowerArrayList.size();

        for (int i = 0; i < max; i++) {
            lower = lowerArrayList.get(i);
            upper = upperArrayList.get((max - 1) - i);
            System.out.println(lower + " " + upper);
        }

        return;
    }
}

Iterator を実装してもいいんですけど,再利用する可能性が低いなら,こっちの方が手っ取り早いし柔軟だと思います。連結リストに対して頻繁にランダムアクセスするのが論外だとしても,ArrayList に関する限り,単純にクルクル回すだけなら……まぁどっちでもええんじゃないの?と思うんですが。

一方で,こちらの話が本当にあるとしたら,根本的に重大な設計上のミスがある考えなくちゃいけないなぁ……と。

例えば他のフレームワークから
Listを所得してるとき。
中でどのListが生成されているかを調べなきゃ行けないし
バージョンによって変わるかもしれない。

今までArrayListが返ってきていたから
getでfor文を書いていたとき。
フレームワークをバージョンアップして
もしもそこがLinkedListになっていたら
それだけでかなりのパフォーマンスの低下になる。

Yoshioriの日記: JavaはIteratorを使うべき理由

引用前段にあるように,List が返されているところでクルクル回すには,Iterator を使う外にないわけで,「中でどのListが生成されているかを調べ」るなんてことは,やっちゃいけません。もしやっているなら,オブジェクト指向の理解に根本的な誤りがあると考えなくちゃいけません。

ただ,ここで Iterator を使うのは,そのメソッドが得体の知れない List を返すからなわけで(LinkedList に対するランダムアクセスはすべきでない,という意味で「できない」),Java を使っているからではありません。これに対して ArrayList が返ることを明示しているメソッドなら,返値を get() でアクセスしたって別に構わないと思うんですが……。将来,この返値が LinkedList になる場合があるとしても,単純に契約違反になるわけですから,どちみち影響調査の対象になってしまいます。ということで,Iterator 使うべしな話を ArrayList(ひいては Java 一般)にまで拡張(敷衍)するのは,さすがに無理があるんじゃないか,と……。

まぁ,なんつーか,考えて設計/実装してるなら(自分の設計/実装を他人に説明できるなら),どっちでもええんじゃないの,と思っただけ。

Trackback
Trackback URL:
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN