目次

目次

ArrayListなににいれる

鈴木
鈴木
最終更新日2016/11/09 投稿日2016/11/09

弊社エンジニア福山さんいわく

あたらしいコードでは

ArrayList<String> ltsv = new ArrayList<String>();

ってやってて自分は

List<String> ltsv = new ArrayList<String>();

こう教わったんだけどどうなの?という命を受けて調査いたしました。

私もArrayListは作成コストがかかりすぎるため よりコストのかからないディクショナリを作成せよ、と 教わった記憶があるのですが本当なのか確認してみようと思います。

コーディング的な観点では

ListはインターフェースでありArrayListはその実装です。 なのでArrayListと宣言してしまうとArrayListしかいれられないため ListにしておけばArrayListでもLinkedListでもVectorでも入れられて 拡張性が高いよっていう主張みたいです。

しかしながらこれは本当でしょうか。 ArrayList(インデックス付き配列)にしたものをLinkedList(インデックス無し配列)などにするでしょうか。 あるいは、具象クラスの代入に対して上位抽象クラスを宣言して拡張性が高い、という主張をするならば

object ltsv = new ArrayList<String>();

こうなってしまいます。

実装的な観点では

調べたところ昔は

ArrayList ltsv = new ArrayList();

こういうふうにかけたんですが今はジェネリクスになっており型を明示しないと怒られるようです。

ArrayList<String> ltsv = new ArrayList<String>();

注意点としてはintなどのプリミティブ型が入れられないのでラッパー(Integerなど)を使えとのこと。

下記のようにいちまんかいaddする処理をいちまんかい繰り返す時間を計測してみました。

  long start = System.currentTimeMillis();
  for(int i = 0; i < 10000; i++)
  {
    ArrayList<String> ltsv = new ArrayList<String>();
    for(int j = 0; j < 10000; j++)
    {
      ltsv.add("test" + Integer.toString(j));
    }
    // System.out.println( StringUtils.join(ltsv, "\t") );
  }

  long end = System.currentTimeMillis();
  long isb = end - start;
  System.out.println("かかった時間:  " + isb);

・ArrayList

かかった時間: 7832

・AbstractList

かかった時間: 7849

・List

かかった時間: 7804

・怒られながらも宣言なし

かかった時間: 7937

・AbstractCollection

かかった時間: 7876

いわくどれも8秒弱で速度的には変わらないという結果になりました。

結論:どうでもいい。

補足

その昔(今でも?)C#に於いてArrayListは可変であり、 型はなんでもOKというような配列であり、List(ジェネリッククラス)が 導入されるまではとてもコストがかかる配列でした。 なので私もArrayListよりもListのほうがよりよいものだと 思い込んでいたのですが、Javaに於いてはArrayListでも 型宣言を強制することによってキャストする必要が無いなどの パフォーマンスチューニングが図られているため 特に気にする必要はないのかなと思いました。

鈴木

和服とvapeとСистемаと醗酵とたまごふわふわとカッティングシェイプスとジャージークラブとjuke/fwkに傾倒する人です

目次