Java | 1 日 90 分 × 7 日アプリ学習 初級編:List を使うアプリ

Web APP Java
スポンサーリンク

7日目のゴール

7日目のテーマは
「ArrayList を“単なる便利クラス”から、“アプリの中のデータ構造”として意識して使えるようになること」 です。

ここまでであなたはすでに、

ArrayList は伸び縮みする
クラスのフィールドとして持てる
オブジェクトのリストを扱える
検索・更新・削除・並び替えができる
Comparator で並び替えルールを変えられる

というところまで来ています。

7日目では、それらをまとめて、

「現実っぽいアプリの中で ArrayList をどう設計するか」
「どこまでを ArrayList に任せて、どこからを自分のルールにするか」

を、小さな「図書館貸出管理アプリ」を題材にして整理していきます。


今日の題材:図書館の貸出管理ミニアプリ

アプリの世界を言葉で先に決める

まずはコードを書く前に、「世界観」を言葉で決めます。

本がある
利用者がいる
貸出記録がある

この3つが登場人物です。

本は「タイトル・著者・ID」
利用者は「名前・会員番号」
貸出記録は「どの本を・誰が・いつ借りたか」

これらをクラスで表現し、
その「集まり」を ArrayList で管理していきます。


Book・User・Loan をクラスで表現する

Book クラス

public class Book {
    String id;
    String title;
    String author;

    Book(String id, String title, String author) {
        if (id == null || id.isEmpty()) {
            throw new IllegalArgumentException("ID は必須です。");
        }
        if (title == null || title.isEmpty()) {
            throw new IllegalArgumentException("タイトルは必須です。");
        }
        if (author == null || author.isEmpty()) {
            throw new IllegalArgumentException("著者は必須です。");
        }
        this.id = id;
        this.title = title;
        this.author = author;
    }

    void show() {
        System.out.println("ID: " + id + " / タイトル: " + title + " / 著者: " + author);
    }
}
Java

ここで大事なのは、
「本を一意に識別するための ID を持っている」ことです。
タイトルが同じ本があっても、ID が違えば別の本として扱えます。

User クラス

public class User {
    String memberId;
    String name;

    User(String memberId, String name) {
        if (memberId == null || memberId.isEmpty()) {
            throw new IllegalArgumentException("会員番号は必須です。");
        }
        if (name == null || name.isEmpty()) {
            throw new IllegalArgumentException("名前は必須です。");
        }
        this.memberId = memberId;
        this.name = name;
    }

    void show() {
        System.out.println("会員番号: " + memberId + " / 名前: " + name);
    }
}
Java

利用者も同じく、「会員番号」で一意に識別します。

Loan クラス(貸出記録)

public class Loan {
    Book book;
    User user;
    String date;

    Loan(Book book, User user, String date) {
        if (book == null) {
            throw new IllegalArgumentException("本は必須です。");
        }
        if (user == null) {
            throw new IllegalArgumentException("利用者は必須です。");
        }
        if (date == null || date.isEmpty()) {
            throw new IllegalArgumentException("日付は必須です。");
        }
        this.book = book;
        this.user = user;
        this.date = date;
    }

    void show() {
        System.out.println("【貸出】日付: " + date);
        System.out.print("  本: ");
        book.show();
        System.out.print("  利用者: ");
        user.show();
    }
}
Java

ここが今日の重要ポイントのひとつです。

Loan は「Book と User を“参照”として持っている」
つまり、
「貸出記録は、本と利用者の“関係”を表すオブジェクト」
になっています。


ArrayList で「集まり」を管理するクラスを作る

Library クラスの役割を決める

Library クラスには、こういう責務を持たせます。

本の一覧を管理する
利用者の一覧を管理する
貸出記録の一覧を管理する
本を登録する
利用者を登録する
本を貸し出す
貸出中の本を一覧表示する

これらを、すべて ArrayList で支えます。

Library クラスのフィールドとコンストラクタ

import java.util.ArrayList;

public class Library {
    ArrayList<Book> books;
    ArrayList<User> users;
    ArrayList<Loan> loans;

    Library() {
        books = new ArrayList<>();
        users = new ArrayList<>();
        loans = new ArrayList<>();
    }
}
Java

ここで大事なのは、

本のリスト
利用者のリスト
貸出記録のリスト

という「3種類の可変長データ」を、
それぞれ別の ArrayList で管理していることです。


本と利用者の登録

本の登録メソッド

void addBook(Book book) {
    if (book == null) {
        System.out.println("null の本は登録できません。");
        return;
    }
    books.add(book);
}
Java

利用者の登録メソッド

void addUser(User user) {
    if (user == null) {
        System.out.println("null の利用者は登録できません。");
        return;
    }
    users.add(user);
}
Java

ここはシンプルですが、
「ArrayList を直接触らず、意味のあるメソッドで操作する」
というこれまでの流れを踏襲しています。


ID で本・利用者を検索する

本を ID で探す

Book findBookById(String id) {
    if (id == null || id.isEmpty()) {
        return null;
    }
    for (Book b : books) {
        if (b.id.equals(id)) {
            return b;
        }
    }
    return null;
}
Java

利用者を会員番号で探す

User findUserByMemberId(String memberId) {
    if (memberId == null || memberId.isEmpty()) {
        return null;
    }
    for (User u : users) {
        if (u.memberId.equals(memberId)) {
            return u;
        }
    }
    return null;
}
Java

ここで改めて確認したいのは、

ArrayList の中身を「先頭から順番に見る」線形探索
ID や会員番号のような「一意なキー」で探す

というパターンです。


本を貸し出す処理を ArrayList で組み立てる

貸出メソッドの全体像

boolean loanBook(String bookId, String memberId, String date) {
    Book book = findBookById(bookId);
    if (book == null) {
        System.out.println("そのIDの本は存在しません。");
        return false;
    }

    User user = findUserByMemberId(memberId);
    if (user == null) {
        System.out.println("その会員番号の利用者は存在しません。");
        return false;
    }

    if (isBookOnLoan(book)) {
        System.out.println("その本はすでに貸出中です。");
        return false;
    }

    Loan loan = new Loan(book, user, date);
    loans.add(loan);
    System.out.println("貸出を登録しました。");
    return true;
}
Java

ここでやっていることを、順番に言葉にします。

ID から本を探す
会員番号から利用者を探す
その本がすでに貸出中かどうかをチェックする
問題なければ Loan を作って、loans に追加する

つまり、

「複数の ArrayList をまたいで、“アプリとして意味のある処理”を組み立てている」
という状態です。

貸出中かどうかを判定するメソッド

boolean isBookOnLoan(Book book) {
    for (Loan loan : loans) {
        if (loan.book == book) {
            return true;
        }
    }
    return false;
}
Java

ここでのポイントは、

loan.book == book を使っていることです。
これは「同じ Book オブジェクトかどうか」を参照で比較しています。

ID で比較してもいいですが、
ここでは「同じインスタンスかどうか」で判定しています。


貸出中の本を一覧表示する

loans の中身をそのまま見せる

void showLoans() {
    System.out.println("=== 貸出中の本一覧 ===");
    if (loans.isEmpty()) {
        System.out.println("現在、貸出中の本はありません。");
        return;
    }
    for (Loan loan : loans) {
        loan.show();
    }
}
Java

ここでは、

貸出記録のリスト(ArrayList<Loan>)を
そのまま「ビュー」として使っています。

Loan が Book と User を参照で持っているので、
「Loan を表示するだけで、本と利用者の情報も一緒に見える」
という構造になっています。


Main から見た「アプリとしての顔」

全体を通した利用イメージ

public class Main {
    public static void main(String[] args) {
        Library lib = new Library();

        Book b1 = new Book("B001", "Java入門", "山田太郎");
        Book b2 = new Book("B002", "アルゴリズム図鑑", "佐藤花子");
        lib.addBook(b1);
        lib.addBook(b2);

        User u1 = new User("U001", "田中一郎");
        lib.addUser(u1);

        lib.loanBook("B001", "U001", "2026-05-23");
        lib.showLoans();

        System.out.println("もう一度同じ本を借りようとしてみる");
        lib.loanBook("B001", "U001", "2026-05-24");
    }
}
Java

このコードを眺めてみてください。

Library を作る
本を登録する
利用者を登録する
本を貸し出す
貸出中の本を一覧表示する

Main からは、
「ArrayList」という言葉は一切見えません。

見えているのは、


利用者
貸出
図書館

という“アプリの世界”だけです。

裏側では、

本のリスト(ArrayList<Book>)
利用者のリスト(ArrayList<User>)
貸出記録のリスト(ArrayList<Loan>)

という3つの可変長データが、
静かにアプリを支えています。


7日目で整理しておきたい「ArrayList の本質」

ここまで来たあなたに、ArrayList を一言でまとめるなら、

「アプリの中の“増えたり減ったりするもの”を、順番付きで管理するための器」

です。

配列との違いは「伸び縮みする」ことだけではありません。

クラスのフィールドとして持てる
オブジェクトのリストを扱える
検索・更新・削除・並び替えの土台になる
複数の ArrayList を組み合わせて、「世界」を表現できる

7日目で一番大事なのは、

「ArrayList をどう書くか」ではなく、
「ArrayList をどこに置いて、何の“集まり”を表現させるか」
を考えられるようになることです。

もし余裕があれば、今日の Library に
「返却メソッド(loan を削除する)」
「特定の利用者の貸出一覧を表示する」
などを自分で足してみてください。

そのとき、必ず
「どの ArrayList を、どんな条件でなめるか」
を意識することになります。

そこまで行けたら、
あなたはもう「ArrayList を使う側」ではなく、
「ArrayList を前提にアプリの世界を設計する側」 に立っています。

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