Java : 回答編
回答してみようと思います。
ArrayList<String> list = new ArrayList<String>();
以下、ネタバレ注意
-
-
- -
-
まず、次のように宣言すべきでは?という主張は、残念ながら私はあまり重要ではないと思います。
List<String> list = new ArrayList<String>();
なぜなら、この宣言の形を見るに、ローカル宣言の可能性が高く、そうであるならListに宣言する必要なんてないと思うからです。
この宣言は、型推論があるなら、
var list = new ArrayList<String>();
という宣言ですが、このときに、listがList型で推論されることはないですよね。listにはArrayListしか入り得ないから十分に特化した型を当ててしまって問題ないです。
インターフェースが有用なのは、
class Hoge {
List fuga;
List f (List list);
}
のような外部に公開する部分だと考えます。
-
-
- -
-
では、何が問題かというと、私が許せないと思うのは、初期容量を指定していない所です。このコードは、次のように宣言されるべきです。
ArrayList<String> list = new ArrayList<String>(100);
初期容量を指定しないと、初期容量10で作成され、内部配列が不足したら、長さが倍の配列が確保されて、中身をコピーするような動作をします。
配列のコピーは避けられるものなら避けるべきなので、始めに必要な容量を推定して、なんらかの初期容量を指定すべきです。これを指定していないということは、必要な容量についての検討を怠っているということを暗示していると言えます。
-
-
- -
-
また、そもそも本当にそのArrayListは必要なのでしょうか?ArrayListが消せないかというのは、ArrayListを使ったコードを見るたびに思うことです。あまりにもArrayListである必要がないコードを見すぎたせいなのか、ArrayListを使ったコードには意地悪になっているということもあるのですが。
そのArrayListは、配列ではダメなのでしょうか?ArrayListは配列とよく似ているので、配列で問題ないところにArrayListを使っているケースが多いですが、ArrayListよりも配列の方が軽量ですから、配列でよいなら配列を使っておくべきです。
また、そもそもそのArrayListは本当に必要なのでしょうか?こういうコードを見たことがあります。(Java 1.4のコードです)
void f (HashMap m) { ArrayList list = new ArrayList(); for (Iterator i = m.keySet().iterator(); i.hasNext();) { list.add(m.get((String)i.next())); } /* 以下、listを使った処理 */ }
どこから突っ込んだらよいのかわからないようなコードですが、こんなのはほとんどの場合、そもそもArrayListそのものが不要です。でも、こういうのを見かけるのは、現実には例外的なことではありません。
私がコードを書くときはほとんどArrayListにお目にかかることはない上に、人のコードを見てArrayListが使われているケースはほとんどが非効率な処理になっているので、私にとって、ArrayListは非効率な処理が行われている危険シグナルにリストされています。