4日目のゴール
4日目のテーマは
「ArrayList に入れた“可変長データ”を、探す・更新する・削除するという一連の流れで扱えるようになること」 です。
ここまでであなたはすでに、
配列との違いとしての「伸び縮みする箱」というイメージ
ArrayList をクラスのフィールドとして持つ感覚
1件分をクラス(Task など)で表現し、そのオブジェクトを ArrayList に入れる
というところまで来ています。
4日目ではここから一歩進んで、
「条件に合うデータを ArrayList から探す」
「見つかったデータの中身を変更する」
「条件に合うものだけ削除する」
という、“アプリっぽい操作”を身につけます。
題材は、前回のタスク管理を少しパワーアップさせたものにします。
今日の題材:タスク管理アプリを「使えるレベル」にする
3日目までの状態を振り返る
3日目までで作ったイメージは、こんな感じでした。
Task クラスで「1件分のタスク」を表現する
TaskList クラスで「タスクのリスト(ArrayList<Task>)」を管理する
TaskList に「追加」「一覧表示」「優先度で絞り込み」などのメソッドを持たせる
4日目では、ここにさらに、
タイトルでタスクを探す
見つかったタスクの内容を更新する
タイトルでタスクを削除する
という機能を足していきます。
Task クラスの確認
1件分のタスクの定義
まずは Task を改めて定義しておきます。
public class Task {
String title;
String deadline;
int priority;
Task(String title, String deadline, int priority) {
if (title == null || title.isEmpty()) {
throw new IllegalArgumentException("タイトルは必須です。");
}
if (deadline == null || deadline.isEmpty()) {
throw new IllegalArgumentException("期限は必須です。");
}
if (priority < 1 || priority > 3) {
System.out.println("優先度が範囲外なので 3(低) にします。");
this.priority = 3;
} else {
this.priority = priority;
}
this.title = title;
this.deadline = deadline;
}
void show() {
System.out.println("タイトル: " + title + " / 期限: " + deadline + " / 優先度: " + priority);
}
}
Javaここでの本質は変わりません。
「1件分の情報をまとめて持つ」「コンストラクタで変な値を防ぐ」「show で自己紹介できる」
この3つが押さえられていれば十分です。
TaskList クラスに「探す」を追加する
ArrayList の中から「条件に合うものを探す」考え方
TaskList は、前回まででこんな形でした。
import java.util.ArrayList;
public class TaskList {
ArrayList<Task> tasks;
TaskList() {
tasks = new ArrayList<>();
}
void add(Task task) {
if (task == null) {
System.out.println("null のタスクは追加できません。");
return;
}
tasks.add(task);
}
void showAll() {
System.out.println("=== タスク一覧 ===");
if (tasks.isEmpty()) {
System.out.println("タスクはまだありません。");
return;
}
for (int i = 0; i < tasks.size(); i++) {
System.out.print((i + 1) + "件目: ");
tasks.get(i).show();
}
}
}
Javaここに、「タイトルでタスクを探す」メソッドを追加します。
Task findByTitle(String title) {
if (title == null || title.isEmpty()) {
return null;
}
for (Task t : tasks) {
if (t.title.equals(title)) {
return t;
}
}
return null;
}
Javaこのメソッドでやっていることを、丁寧に言葉にします。
探したいタイトルが null や空文字なら、そもそも探さずに null を返すfor (Task t : tasks) で、リストの中のタスクを1件ずつ取り出すt.title.equals(title) で「タイトルが一致するか」をチェックする
一致したら、その Task をそのまま返す
最後まで見ても見つからなければ null を返す
これが、いわゆる「線形探索」です。
重要なのは、「ArrayList の中身を先頭から順番に見ていく」 というシンプルな考え方です。
見つけたタスクの“中身を更新する”
参照を通じて中身が変わる、という感覚
さっきの findByTitle は、Task オブジェクトを返していました。
Task t = list.findByTitle("Java の勉強");
Javaここで返ってくる t は、
ArrayList の中に入っている Task と「同じもの」です。
つまり、こう書くと:
if (t != null) {
t.priority = 1;
}
Javaリストの中の Task の priority も、1 に変わります。
ここがとても大事なポイントです。
「ArrayList に入っているのは“オブジェクトそのもの”ではなく、“オブジェクトへの参照”」
だから、
findByTitle で取り出した Task のフィールドを変える
→ リストの中の Task も同じように変わる
という動きになります。
更新専用メソッドを用意する
直接フィールドをいじるのが気持ち悪ければ、
TaskList に「更新メソッド」を用意してもいいです。
boolean updatePriority(String title, int newPriority) {
if (newPriority < 1 || newPriority > 3) {
System.out.println("優先度は 1〜3 で指定してください。");
return false;
}
Task t = findByTitle(title);
if (t == null) {
System.out.println("そのタイトルのタスクは見つかりません。");
return false;
}
t.priority = newPriority;
return true;
}
Javaこれで Main はこう書けます。
list.updatePriority("Java の勉強", 1);
Java「タイトルでタスクを探して、優先度を更新する」という一連の流れを、
1つのメソッドに閉じ込めた形です。
条件に合うタスクを“削除する”
remove とループの組み合わせ
次は「タイトルでタスクを削除する」メソッドです。
boolean removeByTitle(String title) {
if (title == null || title.isEmpty()) {
return false;
}
for (int i = 0; i < tasks.size(); i++) {
Task t = tasks.get(i);
if (t.title.equals(title)) {
tasks.remove(i);
return true;
}
}
return false;
}
Javaここでのポイントを深掘りします。
インデックス付きの for 文で回しているtasks.get(i) で i 番目のタスクを取り出す
タイトルが一致したら tasks.remove(i) でそのタスクを削除する
削除したらすぐ return true でメソッドを終わらせる
なぜ拡張 for 文ではなく、インデックス付き for 文を使っているかというと、
「ループ中に remove するときは、インデックスで回したほうが安全」
だからです。
拡張 for 文で remove をすると、ConcurrentModificationException という例外が出ることがあります。
初心者のうちは、
「削除を伴うループは、インデックス付きで書く」
と覚えておくと安心です。
Main から見た「探す・更新・削除」の流れ
一連の操作を通して眺めてみる
ここまでの TaskList に、
findByTitle・updatePriority・removeByTitle を足したとします。
TaskList 全体はこうなります。
import java.util.ArrayList;
public class TaskList {
ArrayList<Task> tasks;
TaskList() {
tasks = new ArrayList<>();
}
void add(Task task) {
if (task == null) {
System.out.println("null のタスクは追加できません。");
return;
}
tasks.add(task);
}
void showAll() {
System.out.println("=== タスク一覧 ===");
if (tasks.isEmpty()) {
System.out.println("タスクはまだありません。");
return;
}
for (int i = 0; i < tasks.size(); i++) {
System.out.print((i + 1) + "件目: ");
tasks.get(i).show();
}
}
Task findByTitle(String title) {
if (title == null || title.isEmpty()) {
return null;
}
for (Task t : tasks) {
if (t.title.equals(title)) {
return t;
}
}
return null;
}
boolean updatePriority(String title, int newPriority) {
if (newPriority < 1 || newPriority > 3) {
System.out.println("優先度は 1〜3 で指定してください。");
return false;
}
Task t = findByTitle(title);
if (t == null) {
System.out.println("そのタイトルのタスクは見つかりません。");
return false;
}
t.priority = newPriority;
return true;
}
boolean removeByTitle(String title) {
if (title == null || title.isEmpty()) {
return false;
}
for (int i = 0; i < tasks.size(); i++) {
Task t = tasks.get(i);
if (t.title.equals(title)) {
tasks.remove(i);
return true;
}
}
return false;
}
}
JavaMain は、こんな感じで書けます。
public class Main {
public static void main(String[] args) {
TaskList list = new TaskList();
list.add(new Task("Java の勉強", "2026-05-30", 2));
list.add(new Task("買い物に行く", "2026-05-25", 3));
list.add(new Task("ランニング", "2026-05-24", 1));
System.out.println("----- 初期状態 -----");
list.showAll();
System.out.println("----- 優先度を更新 -----");
list.updatePriority("Java の勉強", 1);
list.showAll();
System.out.println("----- タスクを削除 -----");
list.removeByTitle("買い物に行く");
list.showAll();
}
}
Javaこのコードを眺めてみてください。
タスクリストを作る
タスクを追加する
タスク一覧を見る
特定のタスクの優先度を更新する
特定のタスクを削除する
Main は、
「ArrayList をどう回すか」「どのインデックスを消すか」 を一切意識していません。
意識しているのは、
タスクリスト
タスクを追加する
タスクを探す・更新する・削除する
という“アプリとしての操作”だけです。
これが、4日目で一番大事な感覚です。
4日目で絶対に押さえてほしい本質
今日いちばん大事なのは、
「ArrayList に入っている“オブジェクトの集まり”を、条件で探して・中身を変えて・消す」という一連の流れをイメージできたかどうか です。
1件分をクラスで表現する(Task)
そのクラスのインスタンスを ArrayList に詰める(ArrayList<Task>)
ArrayList 自体はクラスの中に隠し、
外からは「意味のある操作(追加・一覧・検索・更新・削除)」だけをメソッドとして公開する
そしてもう一つ、とても重要なポイント。
「find で取り出したオブジェクトを変更すると、リストの中身も変わる」
これは、オブジェクトが「参照」で扱われているからです。
この感覚が入っていれば、
5日目以降にやる「複数条件での検索」「ソート」「別のリストへのコピー」なども、
自然に理解できるようになっていきます。

