第8回 で入門シリーズ前半が完結し、いよいよ 応用編 に入ります。 今回学ぶ ArrayList(アレイリスト)は、第 5 回で学んだ 配列の発展形 で、実務で最もよく使われる「データの集まり」を扱う仕組みです。
「配列だけじゃダメなの?」── 配列には 「サイズを後から変えられない」 という大きな制約があります。ArrayList を使えばこの制約から解放され、自由に要素を追加・削除できるようになります。
この記事のゴール
「ArrayList とは何か」「配列との違い」「要素の追加・削除・検索の書き方」「ジェネリクス <Type> の意味」を理解することです。
なぜ ArrayList が必要?(配列の弱点)
第 5 回で学んだ配列は、こんな書き方でした:
int[] scores = {80, 75, 90, 60, 85}; // サイズ 5 で固定
scores[5] = 100; // ❌ ArrayIndexOutOfBoundsException!
配列の致命的な弱点は、**「作るときにサイズを決めないといけない」**こと。新メンバーが増えてもサイズを変えられず、データを動的に追加できません。
そこで登場するのが ArrayList。これは Java 標準ライブラリに用意された 「自動でサイズが伸び縮みする配列」 です。
💡 ArrayList = ゴム製のロッカー。ロッカーが足りなくなったら自動で増設してくれる、便利な仕組みです。
ArrayList の基本(まずはこの 1 行)
import java.util.ArrayList; // 使う前に必ず import が必要
public class ArrayListDemo {
public static void main(String[] args) {
// ArrayList を作る(<String> = 文字列だけ入る型指定)
ArrayList<String> names = new ArrayList<>();
names.add("佐藤"); // 末尾に追加 → ["佐藤"]
names.add("田中"); // 末尾に追加 → ["佐藤", "田中"]
names.add("鈴木"); // 末尾に追加 → ["佐藤", "田中", "鈴木"]
System.out.println(names); // → [佐藤, 田中, 鈴木]
}
}
1 行ずつ解説
import java.util.ArrayList;
ArrayList は標準ライブラリの中に入っている部品です。使う前に import(取り込み) が必要です。
ArrayList<String> names = new ArrayList<>();
ArrayList<String>: 「String 型だけを入れる ArrayList」と型を明示<String>の部分が ジェネリクス(後述)new ArrayList<>(): 空の ArrayList を作る(右側の<>は省略可、型推論される)
names.add("佐藤");
add() メソッドで末尾に要素を追加します。配列のように names[0] = ... のような書き方はしません。
ジェネリクス<>の意味
ジェネリクス(<Type>) は、ArrayList の中に入れたい型を指定するための仕組みです。
ArrayList<String> names = new ArrayList<>(); // String を入れる
ArrayList<Integer> scores = new ArrayList<>(); // Integer(int の参照型版)を入れる
ArrayList<Double> heights = new ArrayList<>(); // Double を入れる
💡 重要: int / double / boolean などの 基本型は ArrayList に直接入れられません。代わりに
Integer/Double/Booleanという 参照型(ラッパークラス) を使います。 ただし Java の オートボクシング 機能のおかげで、見た目は int をそのまま入れられるように書けます:ArrayList<Integer> nums = new ArrayList<>(); nums.add(10); // ← int 10 が自動で Integer に変換される
よく使うメソッド一覧
| メソッド | 用途 | 例 |
|---|---|---|
add(要素) | 末尾に追加 | list.add("A"); |
add(index, 要素) | 指定位置に挿入 | list.add(0, "X"); |
get(index) | 要素を取得(配列の [i] の代わり) | list.get(0); |
set(index, 要素) | 要素を上書き | list.set(0, "Z"); |
remove(index) | 指定位置を削除 | list.remove(0); |
size() | 要素数を取得(配列の length 相当) | list.size(); |
contains(要素) | 要素を含むか確認 | list.contains("A"); |
indexOf(要素) | 要素の位置を返す | list.indexOf("A"); |
isEmpty() | 空かどうかを確認 | list.isEmpty(); |
clear() | 全要素を削除 | list.clear(); |
⚠ 超重要: 配列は
.length(プロパティ)、ArrayList は.size()(メソッド)。違いに注意!
実例: 名前リストを操作してみる
import java.util.ArrayList;
public class NameListDemo {
public static void main(String[] args) {
// String 型の ArrayList を作成
ArrayList<String> names = new ArrayList<>();
// 要素を追加(末尾に追加されていく)
names.add("佐藤"); // → [佐藤]
names.add("田中"); // → [佐藤, 田中]
names.add("鈴木"); // → [佐藤, 田中, 鈴木]
// 要素を取り出す(0 始まりは配列と同じ)
System.out.println(names.get(0)); // → 佐藤
System.out.println(names.get(2)); // → 鈴木
// 要素を書き換え
names.set(1, "山田"); // 田中 → 山田に置き換え
System.out.println(names); // → [佐藤, 山田, 鈴木]
// 要素を削除
names.remove(0); // 0 番目(佐藤)を削除
System.out.println(names); // → [山田, 鈴木]
// 要素数を取得(配列の length に相当)
System.out.println("人数: " + names.size()); // → 人数: 2
// 含むかチェック
System.out.println(names.contains("山田")); // → true
}
}
ArrayList をループで処理する
第 4 回で学んだ拡張 for 文と組み合わせると、全要素を簡単に処理できます。
ArrayList<String> names = new ArrayList<>();
names.add("佐藤");
names.add("田中");
names.add("鈴木");
// 拡張 for 文:配列のときと書き方は同じ!
for (String name : names) {
System.out.println(name + "さん");
}
// → 佐藤さん
// → 田中さん
// → 鈴木さん
通常の for 文を使う場合は .size() を使います:
for (int i = 0; i < names.size(); i++) { // 配列の .length → ArrayList は .size()
System.out.println(names.get(i)); // 配列の [i] → ArrayList は .get(i)
}
配列と ArrayList の使い分け
| 項目 | 配列 | ArrayList |
|---|---|---|
| サイズ | 固定 | 可変(自動拡張) |
| 要素アクセス | arr[i] | list.get(i) |
| 要素数 | arr.length | list.size() |
| 要素の追加 | できない | add() で OK |
| 要素の削除 | できない(穴埋め不可) | remove() で OK |
| 性能 | 速い | やや遅い(でも実用上問題なし) |
| 使い分け | サイズが完全に決まっているときだけ | ほとんどの場面で OK |
💡 実務では 90% 以上が ArrayList を使います。配列は「サイズが完全に決まっている」「最高性能が必要」な特殊用途と考えていいでしょう。
ハマりがちなエラー TOP3
エラー① import を書き忘れる
ArrayList<String> list = new ArrayList<>(); // ❌ cannot find symbol
対処: ファイルの先頭に import java.util.ArrayList; を書く。IntelliJ や VS Code は自動補完してくれることが多いです。
エラー② int のような基本型を <> に直接書く
ArrayList<int> nums = new ArrayList<>(); // ❌ コンパイルエラー
ArrayList<Integer> nums = new ArrayList<>(); // ⭕ Integer を使う
対処: int → Integer、double → Double、boolean → Boolean などのラッパークラスを使う。
エラー③ ループ中に remove() を呼ぶ
for (String s : list) {
if (s.equals("田中")) {
list.remove(s); // ❌ ConcurrentModificationException
}
}
対処: 拡張 for の途中で remove するとエラーになります。Iterator の remove() を使うか、通常 for で逆順に走査するのが定石です。
for (int i = list.size() - 1; i >= 0; i--) {
if (list.get(i).equals("田中")) {
list.remove(i);
}
}
編集部より
ArrayList を覚えると、Java プログラミングの実用度が一気に上がります。HashMap・HashSet など他のコレクションも、ArrayList の延長で理解できますよ!
練習問題
以下のプログラムを書いてみましょう。
ArrayList
に 5 つの整数 {72, 85, 60, 94, 50} を追加 し、合計と平均を計算して表示してください。
解答例
import java.util.ArrayList;
public class ScoreListDemo {
public static void main(String[] args) {
// Integer の ArrayList を作成
ArrayList<Integer> scores = new ArrayList<>();
// 5 つの値を追加(int は自動で Integer に変換される)
scores.add(72);
scores.add(85);
scores.add(60);
scores.add(94);
scores.add(50);
// 合計を計算
int total = 0;
for (int s : scores) { // 拡張 for で全要素を取り出す
total += s; // 合計に加算
}
// 平均を計算(整数除算で小数点以下は切り捨て)
int average = total / scores.size();
System.out.println("合計: " + total); // → 361
System.out.println("平均: " + average); // → 72
}
}
まとめ
第 9 回では、以下を学びました。
- ✅ ArrayList はサイズが自動で伸び縮みする「可変長配列」
- ✅ 使う前に
import java.util.ArrayList;が必要 - ✅
<Type>(ジェネリクス) で入れる型を指定 - ✅ よく使うメソッド:
add/get/set/remove/size/contains - ✅ 配列の
.lengthに対し、ArrayList は.size() - ✅ 基本型はラッパークラス(Integer/Double 等)で使う
次回は、オブジェクト指向の 真打ちである 「継承・インターフェース」 を学びます。 クラスを 「再利用・拡張」 する仕組みで、Java の真の威力が見えてきますよ。お楽しみに!