Java | 2週間で身につく、アプリを作りながら学ぶJavaの基本 - 5日目

Java Java
スポンサーリンク

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リストの中の「メニュー表示」「入力処理」「削除処理」などを、
メソッドとして分けていくことで、コードを一気に読みやすくしていきます。

タイトルとURLをコピーしました