5日目のゴールとテーマ
5日目のテーマは
「配列より“柔軟なリスト”を使って、追加・削除ができるアプリに近づく」 です。
4日目までで、配列を使って「複数のデータをまとめて扱う」ことができるようになりました。
ただ、配列には大きな弱点があります。
長さをあとから変えられない
途中に要素を挿入したり、削除したりしづらい
現実のアプリでは、「増えたり減ったりするデータ」を扱うことが多いです。
そこで今日は、
ArrayList(可変長のリスト)を使う
要素の追加・取得・削除を覚える
for / 拡張for と組み合わせて扱う
簡単な「ToDoリスト風ミニアプリ」を作る
ここまでを目指します。
配列の限界をもう少しだけ感じてみる
「増やしたいのに、増やせない」という窮屈さ
例えば、4日目の点数管理でこう書きました。
int[] scores = new int[5];
Javaここで「やっぱり6教科にしたい」と思ったら、
コードを書き換えて、new int[6] にしなければいけません。
しかも、すでに入っているデータを引き継ぐのも面倒です。
また、「途中の要素を削除したい」ときも厄介です。
配列は「長さが固定」なので、
削除というより「詰め直し」に近いことをしないといけません。
こういうときに、「もっと柔軟に増減できるリストが欲しい」という気持ちが生まれます。
その欲望に応えてくれるのが、ArrayList です。
ArrayListとは何か
「サイズが変えられる“配列っぽいリスト”」
ArrayList は、Javaが標準で用意している「可変長のリスト」です。
イメージとしては、
中身の型は1種類にそろえる
要素にはインデックス(0, 1, 2, …)でアクセスできる
必要に応じて、あとからいくらでも追加できる
途中の要素を削除すると、自動で詰めてくれる
という、「配列の便利版」です。
使うためには、まず import が必要です。
import java.util.ArrayList;
Javaそして、こう宣言します。
ArrayList<String> names = new ArrayList<String>();
Javaここでのポイントをかみ砕きます。
ArrayList<型>
→ 「このリストには、この型のデータだけを入れます」という宣言
→ <String> なら「文字列のリスト」
→ <Integer> なら「整数のリスト」
names
→ リストの変数名
new ArrayList<String>()
→ 実際に中身を持った空のリストを作る
最近のJavaでは、右側を省略してこう書くことも多いです。
ArrayList<String> names = new ArrayList<>();
Java今日はどちらの書き方でもOKです。
ArrayListに要素を追加する
addメソッドでどんどん足していける
ArrayListに要素を追加するには、add メソッドを使います。
ArrayList<String> names = new ArrayList<>();
names.add("山田");
names.add("佐藤");
names.add("鈴木");
Javaこれで、names には3つの要素が入ります。
インデックスと中身はこうなります。
0番目 → “山田”
1番目 → “佐藤”
2番目 → “鈴木”
配列と同じように、0から始まることは変わりません。
要素を取り出す・数を調べる
get と size をセットで覚える
ArrayListから要素を取り出すには、get メソッドを使います。
String first = names.get(0); // "山田"
String second = names.get(1); // "佐藤"
Java配列の names[0] に相当するのが、ArrayList の names.get(0) です。
要素数(長さ)を知りたいときは、size メソッドを使います。
int count = names.size(); // 3
Java配列の length に相当するのが、ArrayList の size() です。
ここが少しだけ違うので、意識しておいてください。
配列
→ 配列変数.length(フィールド)
ArrayList
→ リスト変数.size()(メソッド)
ArrayListとfor文を組み合わせる
インデックスで回すパターン
ArrayListも、配列と同じように for 文で回せます。
ArrayList<String> names = new ArrayList<>();
names.add("山田");
names.add("佐藤");
names.add("鈴木");
for (int i = 0; i < names.size(); i++) {
String name = names.get(i);
System.out.println((i + 1) + "人目: " + name);
}
Javaここでのポイントは、
i < names.size()
→ 配列のときの i < 配列.length と同じパターン
→ 「0から size 未満」まで回す
names.get(i)
→ i番目の要素を取り出す
というところです。
拡張for文(for-each)でもっとシンプルに書く
「インデックスがいらないとき」はこっちが読みやすい
インデックスを使わず、「全要素を順番に処理するだけ」でいいなら、
拡張 for 文(for-each)を使うとスッキリします。
ArrayList<String> names = new ArrayList<>();
names.add("山田");
names.add("佐藤");
names.add("鈴木");
for (String name : names) {
System.out.println("名前: " + name);
}
Java読み方は、「names の中の要素を、順番に name に取り出していく」です。
配列のときと同じ書き方で使えます。
インデックスが必要なとき
→ ふつうの for 文(i を使う)
インデックスが不要なとき
→ 拡張 for 文(for-each)
と使い分けると、コードが読みやすくなります。
要素を削除する・挿入する
remove と add(位置, 値)
ArrayListの強みは、「途中の要素を削除・挿入しやすい」ことです。
要素を削除するには、remove を使います。
ArrayList<String> names = new ArrayList<>();
names.add("山田");
names.add("佐藤");
names.add("鈴木");
names.remove(1); // インデックス1の要素("佐藤")を削除
Javaこのあと、names の中身はこうなります。
0番目 → “山田”
1番目 → “鈴木”
削除したあとの要素は、自動的に前に詰められます。
途中に挿入したいときは、add(インデックス, 値) を使います。
names.add(1, "高橋"); // インデックス1の位置に「高橋」を挿入
Javaこのあと、names の中身はこうなります。
0番目 → “山田”
1番目 → “高橋”
2番目 → “鈴木”
配列だとかなり面倒な「削除・挿入」が、
ArrayListだとメソッド1つでできる、というのが大きな魅力です。
5日目のミニアプリ:簡易ToDoリスト
「追加・一覧・削除」ができる小さなアプリ
ここまでの内容を組み合わせて、
「テキストベースの簡易ToDoリスト」を作ってみましょう。
やりたいことはシンプルです。
タスクを追加する
タスク一覧を表示する
タスクを削除する
0を選ぶまでメニューを繰り返す
コードはこうなります。
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList<String> tasks = new ArrayList<>();
while (true) {
System.out.println("=== 簡易ToDoリスト ===");
System.out.println("1: タスクを追加する");
System.out.println("2: タスク一覧を表示する");
System.out.println("3: タスクを削除する");
System.out.println("0: 終了する");
System.out.print("番号を選んでください: ");
int choice = scanner.nextInt();
scanner.nextLine(); // 改行を読み飛ばす
if (choice == 0) {
System.out.println("アプリを終了します。");
break;
} else if (choice == 1) {
System.out.print("追加するタスクを入力してください: ");
String task = scanner.nextLine();
if (task.isEmpty()) {
System.out.println("空のタスクは追加できません。");
} else {
tasks.add(task);
System.out.println("タスクを追加しました。");
}
} else if (choice == 2) {
if (tasks.isEmpty()) {
System.out.println("タスクは登録されていません。");
} else {
System.out.println("=== タスク一覧 ===");
for (int i = 0; i < tasks.size(); i++) {
System.out.println((i + 1) + ": " + tasks.get(i));
}
}
} else if (choice == 3) {
if (tasks.isEmpty()) {
System.out.println("削除できるタスクがありません。");
continue;
}
System.out.println("削除するタスクの番号を入力してください:");
for (int i = 0; i < tasks.size(); i++) {
System.out.println((i + 1) + ": " + tasks.get(i));
}
System.out.print("番号: ");
int index = scanner.nextInt();
scanner.nextLine(); // 改行を読み飛ばす
int realIndex = index - 1;
if (realIndex < 0 || realIndex >= tasks.size()) {
System.out.println("その番号のタスクは存在しません。");
} else {
String removed = tasks.remove(realIndex);
System.out.println("タスク「" + removed + "」を削除しました。");
}
} else {
System.out.println("その番号は無効です。");
}
System.out.println();
}
}
}
Javaここでの重要ポイントを深掘りします。
ArrayList<String> tasks = new ArrayList<>();
→ タスクを文字列として管理するリスト
→ 最初は空だが、add でどんどん増やせる
tasks.isEmpty()
→ リストが空かどうかを true / false で返す
→ 「何もないときの特別な処理」を書きやすくなる
削除時に「表示用の番号」と「内部のインデックス」を分けている
→ ユーザーには 1, 2, 3… と見せる
→ 内部では 0, 1, 2… で管理している
→ realIndex = index - 1; で変換している
scanner.nextInt() のあとに scanner.nextLine() を挟んでいる
→ nextInt は数字だけ読み取って、改行を残してしまう
→ そのまま nextLine を呼ぶと、空行を読んでしまう
→ それを防ぐために、改行を一度読み飛ばしている
このあたりは、Javaの入力まわりでよくハマるポイントです。
「nextInt のあとに nextLine を使うときは、1回 nextLine で改行を捨てる」と覚えておくと楽になります。
ArrayListでよくやるミスと感覚の持ち方
「サイズは size、要素は get、削除は remove」
ArrayListを使い始めるときに、よくごちゃごちゃになるのがここです。
長さを知りたい → size()
要素を取り出したい → get(インデックス)
要素を追加したい → add(値) または add(インデックス, 値)
要素を削除したい → remove(インデックス)
配列と混ざりやすいのは、
配列 → length(フィールド)
ArrayList → size()(メソッド)
という違いです。
ここはもう、「そういうものだ」と割り切って、
何度か書いて体で覚えていくのが一番早いです。
5日目で一番大事な感覚
「ArrayListを使えると、“増えたり減ったりする世界”が扱える」
今日あなたに持ってほしい感覚はこれです。
配列は「長さが決まった棚」
ArrayListは「必要に応じて棚板を増やせる棚」
現実のアプリで扱うデータは、
ほとんどが「増えたり減ったりする」ものです。
タスク
メモ
ユーザー
メッセージ
こういうものを扱うとき、
ArrayList を自然に使えるかどうかで、
コードの書きやすさが大きく変わります。
5日目のまとめと、6日目への予告
今日やったことを短く整理すると、
ArrayList は「サイズを変えられる配列のようなリスト」ArrayList<型> 変数 = new ArrayList<>(); で作るadd で追加、get で取得、size で要素数、remove で削除
for / 拡張for と組み合わせて、全要素を処理できる
簡易ToDoリストのような「追加・一覧・削除」ができるアプリを書ける
6日目は、ここに「メソッド(自分で処理のまとまりを作る)」を足していきます。
ToDoリストの中の「メニュー表示」「入力処理」「削除処理」などを、
メソッドとして分けていくことで、コードを一気に読みやすくしていきます。
