{Java} 配列とリストどっち使うの?

swiftの配列に慣れるとjavaの配列がわからなくなるのでまとめ
この記事の目次 ・生成
・取り出し
・格納
・追加、検索、削除
・ラッパー型とプリミティブ型
・一挙に複数の値をリストに格納するには

配列とリストの違い

配列

・サイズを変更できない
 →追加、削除ができない
・処理が早い
・書き方が簡単(後述)

リスト

・サイズが可変である
 →追加、削除ができる
・処理が遅い
・書き方がややこしい(後述)

あたりをとりあえず押さえとかないといけないらしい。

生成

配列
int[] list = new int[5]; //要素数5個
リスト
List<Integer> list = new ArrayList<Integer>();

配列は要素数を決める必要があるが、リストは可変であるため必要ない。
※配列は宣言と初期化を別々に行うことで宣言の段階では要素数を決める必要は無いが、どうせ使う前に初期化するので実質初めに決めないといけない。

int[] list; //宣言
list = new int[5]; //初期化

あとリストはプリミティブ型を使うことができない(後述)

取り出し

配列
String value = list[0];
リスト
String value = list.get(0);

リストのほうがちょっとめんどくさい。

格納

配列
list[0] = "簡単";
リスト
list.set(0, "ややこしい");

リストのほうがちょっとめんどくさい。

末尾への追加・検索・削除

配列

不可

リスト
list.add("可"); //末尾に"可"を追加する
int index = list.indexOf("検索したい文字や数値"); // indexにキー番号が代入
list.remove(0); //0番目を削除

このへんは全て配列ではできない。

まとめ

配列のほうは追加や削除ができない分、何個入るかわかんないデータとかを取り扱う時はリストのほうが良さそう。
ただ取り出したり格納するだけなら、早くて簡単な配列を使えば良さそう

ただ生成の項目でも少し触れたけど、リストはプリミティブ型を使うことができない。

intとIntegerはどっちも数値を格納できるし、同じように使うことができるけど、Integerは一旦intに変換されて計算されてるみたい。
このIntegerはプリミティブ型に対してラッパー型と呼ばれてるらしい。

要はラッパー型のままループなんかに使ったりすると、毎回変換が行われる分効率の悪いコードになるそう。
長いループでリストに格納されてるデータを使うときなんかは、一旦ループの外でプリミティブ型に変換してから使ってやるべきっぽい。
例えば

suuchi.add(3);
suuchi.add(7);
suuchi.add(4);
suuchi.add(5);
suuchi.add(8);

for (int i = 0; i < suuchi.size(); i++) {
    int temp = suuchi.get(i); //長いループの外でプリミティブ型に変換
    for (int j = 0; j < 1000; j++) {
        System.out.println(temp * j);
    }
    
}

素数*1000回ずつ繰り返されるfor文の中で毎回変換させてたらすごく効率が悪いので、要素数分しか繰り返されない所で自分で変換させてやるほうが良いっぽい。

ていうかこういう時に一々addするのも面倒だと思ったので、

(おまけ)一挙に複数の値をリストに格納

いろいろ方法はあるみたいだが、とりあえず一番シンプルなのはこれ。

List<Integer> list = Arrays.asList(3, 2, 4, 5);

ただこの方法だと可変でなくなるという致命的で致命的な致命的欠点があるので、

Collections.addAll()
List<Integer> list = new ArrayList<Integer>(); //宣言のみ
Collections.addAll(suuchi, 3, 2, 4, 6);

list.add(8) //可変なので追加できる

とすれば、可変のまま一挙に追加できる。

おわり。

追記

覚えやすいように、 配列 → カップ麺(簡単で早い)
リスト → 腕組みしてるラーメン屋のラーメン(めんどくさいけどうまい)
って覚え方を個人的にしてたけど、後者は後から胡椒を.addするとむしろ怒られそうだから理に適ってないことが判明した