1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オブジェクト指向って何?RPGで理解する超入門 Part2(ArrayListをマスターしよう!)

1
Last updated at Posted at 2026-01-06

part2_episode03_title_banner.png

📚 この回で学ぶこと

学習時間: 約35分
難易度: ★★★☆☆(3/5)

学習目標

配列の限界を超えて柔軟なデータ管理を実現しよう!

第2回までの問題点

// 配列は固定サイズ
Player[] party = new Player[4];  // ← 4人で固定!
party[0] = new Player("勇者", 100, 1);
party[1] = new Player("戦士", 120, 2);
// もし5人目が加わったら? → 配列の拡張が大変!

第3回で解決

// ArrayList は可変サイズ
List<Player> party = new ArrayList<>();
party.add(new Player("勇者", 100, 1));
party.add(new Player("戦士", 120, 2));
party.add(new Player("魔法使い", 80, 1));  // ← いくらでも追加可能!

📁 成果物のファイル構成

この回で作成するパーティ管理システムのファイル構成:

📂 rpg_party_system/
├── 📂 src/
│   ├── 📂 com/
│   │   └── 📂 javaquest/
│   │       ├── 📂 model/
│   │       │   └── 📝 Player.java         // プレイヤークラス
│   │       ├── 📂 manager/
│   │       │   ├── 📝 Inventory.java      // インベントリ管理
│   │       │   └── 📝 PartyManager.java   // パーティ管理システム
│   │       └── 📝 RPGSystem.java          // メインシステム
│   └── 📂 practice/
│       ├── 📝 Practice01.java          // 練習問题1
│       ├── 📝 ItemManager.java        // 練習問题2
│       ├── 📝 PlayerSorting.java       // 練習問题3
│       └── 📝 SortablePlayer.java      // 練習用クラス
└── 📝 README.md                     // 実行手順書

パッケージ構成の意味:

  • com.javaquest.model → データクラス(Player等)
  • com.javaquest.manager → 管理クラス(PartyManager等)
  • com.javaquest → メインシステム
  • practice → 練習問題用ファイル

📚GitHub:成果物のサンプルはこちら

💡 この成果物で何を学ぶ?

作るもの

RPG のパーティ&アイテム管理システム

できること

  1. パーティ管理 - メンバーを追加・削除・検索
  2. レベルアップ - 指定したメンバーのレベルを上げる
  3. インベントリ - アイテムを入手・使用・表示

なぜ ArrayList を使うの?

配列(第1回) ArrayList(第3回)
Player[4] → 4人で固定 List<Player> → 何人でもOK
途中で増やせない 自由に追加・削除できる
固定席の教室 🪑🪑🪑🪑 可変席のイベント会場 🪑🪑🪑...

実際のゲーム開発でも ArrayList は必須!

この回で身につくスキル

ArrayList - 可変長リストの操作
ジェネリクス - 型安全なコレクション
拡張for文 - 簡単なループ処理
実務スキル - パーティ管理システム

基礎知識

1. 配列の限界とは?

❌ 配列の問題点

public class ArrayProblem {
    public static void main(String[] args) {
        // 問題1: サイズが固定
        String[] members = new String[3];  // 3人で固定
        members[0] = "勇者";
        members[1] = "戦士";
        members[2] = "魔法使い";
        
        // 4人目を追加したい! → でも配列は満杯
        // members[3] = "僧侶";  // ← ArrayIndexOutOfBoundsException!
        
        // 問題2: 要素の削除が面倒
        // 戦士を外したい → すべての要素をずらす必要
        for (int i = 1; i < members.length - 1; i++) {
            members[i] = members[i + 1];  // 手動でシフト
        }
        members[2] = null;  // 最後の要素をnullにする
        
        // 問題3: 動的な長さ取得が困難
        int activeMembers = 0;
        for (String member : members) {
            if (member != null) {
                activeMembers++;  // nullでない要素を数える
            }
        }
        System.out.println("アクティブメンバー: " + activeMembers);
    }
}

配列の3大問題:

  1. サイズ固定 → 後から変更不可
  2. 要素削除が複雑 → 手動でシフト処理
  3. 動的サイズ管理が困難 → nullチェックが必要

array_vs_arraylist_comparison.png

2. ArrayList - 可変長リスト

ArrayList の解決策

  • ArrayList = 自動で拡張される配列
ArrayListSolution.java
import java.util.ArrayList;
import java.util.List;

public class ArrayListSolution {
    public static void main(String[] args) {
        // 宣言: 初期サイズの指定不要
        List<String> party = new ArrayList<>();
        
        // 追加: 自動で拡張
        party.add("勇者");
        party.add("戦士");
        party.add("魔法使い");
        System.out.println("現在のパーティ: " + party);
        // 出力: [勇者, 戦士, 魔法使い]
        
        // さらに追加: サイズ制限なし
        party.add("僧侶");
        party.add("盗賊");
        System.out.println("拡張後: " + party);
        // 出力: [勇者, 戦士, 魔法使い, 僧侶, 盗賊]
        
        // 削除: 簡単
        party.remove("戦士");  // 値で削除
        // party.remove(1);     // インデックスで削除も可能
        System.out.println("戦士除名後: " + party);
        // 出力: [勇者, 魔法使い, 僧侶, 盗賊]
        
        // サイズ取得: 簡単
        System.out.println("現在のメンバー数: " + party.size());
        // 出力: 4
        
        // 検索: 簡単
        if (party.contains("勇者")) {
            System.out.println("勇者がパーティにいます");
        }
        
        // インデックスでアクセス
        String leader = party.get(0);  // 最初の要素
        System.out.println("パーティリーダー: " + leader);
    }
}

実行結果

現在のパーティ: [勇者, 戦士, 魔法使い]
拡張後: [勇者, 戦士, 魔法使い, 僧侶, 盗賊]
戦士除名後: [勇者, 魔法使い, 僧侶, 盗賊]
現在のメンバー数: 4
勇者がパーティにいます
パーティリーダー: 勇者

配列 vs ArrayList

機能 配列 ArrayList
サイズ 固定 可変
追加 手動拡張 add()
削除 手動シフト remove()
検索 手動ループ contains()
サイズ取得 length size()
型安全 ❌(要型キャスト) ✅(ジェネリクス)

ArrayList の主要メソッド

List<String> list = new ArrayList<>();

// 追加
list.add("要素");              // 末尾に追加
list.add(0, "先頭要素");        // 指定位置に挿入

// 取得
String item = list.get(0);     // インデックスで取得
int size = list.size();        // サイズ取得
boolean exists = list.contains("要素");  // 存在チェック

// 削除
list.remove(0);                // インデックスで削除
list.remove("要素");            // 値で削除
list.clear();                  // 全削除

// その他
boolean empty = list.isEmpty();     // 空チェック
int index = list.indexOf("要素");   // インデックス検索

3. ジェネリクス - 型安全性

generics_diamond_operator.png

ジェネリクス とは?

ジェネリクス = 型を指定してコレクションを作る仕組み

❌ ジェネリクスなし(古い書き方)

// Java 5以前の書き方
ArrayList list = new ArrayList();  // 型指定なし
list.add("文字列");
list.add(123);      // 数値も入れられる(危険)
list.add(true);     // 真偽値も入れられる(危険)

// 取り出し時に型キャスト必要
String str = (String) list.get(0);  // キャスト必要
Integer num = (Integer) list.get(1); // キャスト必要

// 実行時エラーの可能性
String wrong = (String) list.get(1); // ClassCastException!

✅ ジェネリクスあり(推奨書き方)

// Java 5以降の書き方
ArrayList<String> list = new ArrayList<>();  // String型のみ
list.add("文字列");
// list.add(123);    // ← コンパイルエラー!数値は入れられない
// list.add(true);   // ← コンパイルエラー!真偽値は入れられない

// 取り出し時に型キャスト不要
String str = list.get(0);  // キャスト不要、安全

// コンパイル時にエラーチェック
// String wrong = list.get(1);  // コンパイル時に型チェック済み

ジェネリクスの記法

// List(リスト)
List<String> stringList = new ArrayList<String>();    // Java 5-6の書き方
List<String> stringList = new ArrayList<>();          // Java 7以降(推奨)
List<Integer> numberList = new ArrayList<>();         // 整数リスト
List<Player> playerList = new ArrayList<>();          // Playerオブジェクトリスト

// 将来的に学習するMap(第4回で詳しく学習)
// 第4回でHashMapを学習します

ダイヤモンド演算子の省略(Java 7以降)

// Java 6まで: 両側に型を書く必要があった
ArrayList<String> oldWay = new ArrayList<String>();  // 繰り返し

// Java 7以降: 右側の型を省略可能!
ArrayList<String> modernWay = new ArrayList<>();     // スッキリ!

ポイント:

  • <>ダイヤモンド演算子と呼びます
  • 右側の型は自動で推論される(型推論)
  • コードがシンプルで読みやすくなる

4. 拡張for文 - 簡単なループ

enhanced_for_loop_explanation.png

拡張for文(for-each文)は、ArrayListの全要素を簡単に処理できる便利な文法です。

通常のfor文 vs 拡張for文

ArrayList<String> items = new ArrayList<>();
items.add("回復薬");
items.add("マナポーション");
items.add("鉄の剣");

// 通常のfor文(索引を使用)
for (int i = 0; i < items.size(); i++) {
    String item = items.get(i);
    System.out.println("アイテム: " + item);
}

// 拡張for文(簡単!)
for (String item : items) {
    System.out.println("アイテム: " + item);
}

拡張for文のメリット

シンプル: 索引を使わない
安全: 範囲外アクセスエラーが起きない
読みやすい: 意図が明確

使い分け

// 全要素を処理する場合 → 拡張for文
for (Player player : party) {
    player.displayStatus();  // 全メンバーのステータス表示
}

// 特定の位置のみ処理 → 通常のfor文
for (int i = 0; i < party.size(); i++) {
    if (i == 0) {  // リーダーのみ
        party.get(i).displayStatus();
    }
}

実装演習

Step 1: Player クラスの拡張

まず、コレクションで使いやすいように Player クラスを拡張します。

プレイヤークラス(シンプル版)

package com.javaquest.model;

/**
 * プレイヤークラス
 * 
 * 💡 何をするクラス?
 * → ゲームキャラ1人分のデータを管理
 *  (名前、HP、レベル、職業)
 * 
 * 💡 身近な例
 * → ポケモンのステータス画面みたいなもの
 *  「ピカチュウ Lv.25 HP:80/100」
 */
public class Player {
    private String name;
    private int hp;
    private int level;
    private String job;
    
    public Player(String name, int hp, int level, String job) {
        this.name = name;
        this.hp = hp;
        this.level = level;
        this.job = job;
    }
    
    // ゲッター
    public String getName() { return name; }
    public int getHp() { return hp; }
    public int getLevel() { return level; }
    public String getJob() { return job; }
    
    // HP操作
    public void heal(int amount) {
        this.hp += amount;
        System.out.println("💚 " + name + " は " + amount + " 回復!(HP: " + hp + ")");
    }
    
    public void takeDamage(int damage) {
        this.hp -= damage;
        if (this.hp < 0) this.hp = 0;
        System.out.println("💥 " + name + " は " + damage + " ダメージ!(HP: " + hp + ")");
    }
    
    // レベルアップ
    public void levelUp() {
        level++;
        System.out.println("🎉 " + name + " がレベルアップ! Lv." + level);
    }
    
    // 生存確認
    public boolean isAlive() {
        return hp > 0;
    }
    
    @Override
    public String toString() {
        return name + " [" + job + "] Lv." + level + " HP:" + hp;
    }
}

Step 2: PartyManager - パーティ管理システム

インベントリクラス

Inventory.java
package com.javaquest.model;

import java.util.HashMap;
import java.util.Map;

/**
 * インベントリクラス
 * 
 * 💡 何をするクラス?
 * → ゲームのアイテムボックス
 *  (アイテムを入手、使用、一覧表示)
 * 
 * 💡 身近な例
 * → マイクラのインベントリ
 *  「ポーション x5」「エリクサー x2」
 * 
 * 💡 HashMap を使う理由
 * → アイテム名で個数を管理したいから
 *  "ポーション" → 5個
 *  "エリクサー" → 2個
 */
public class Inventory {
    private Map<String, Integer> items;
    private int maxCapacity;
    
    public Inventory(int maxCapacity) {
        this.items = new HashMap<>();
        this.maxCapacity = maxCapacity;
    }
    
    public boolean addItem(String name, int count) {
        if (!items.containsKey(name) && items.size() >= maxCapacity) {
            System.out.println("❌ インベントリが満杯です");
            return false;
        }
        
        int current = items.getOrDefault(name, 0);
        items.put(name, current + count);
        System.out.println("✅ " + name + " を " + count + " 個入手(合計: " + (current + count) + ")");
        return true;
    }
    
    public boolean useItem(String name, int count) {
        if (!items.containsKey(name)) {
            System.out.println("❌ " + name + " を持っていません");
            return false;
        }
        
        int current = items.get(name);
        if (current < count) {
            System.out.println("❌ " + name + " が足りません(所持: " + current + ")");
            return false;
        }
        
        int newCount = current - count;
        if (newCount == 0) {
            items.remove(name);
        } else {
            items.put(name, newCount);
        }
        System.out.println("✅ " + name + " を " + count + " 個使用(残り: " + newCount + ")");
        return true;
    }
    
    public void showInventory() {
        System.out.println("\n┌─────────────────────┐");
        System.out.println("│   🎒 インベントリ   │");
        System.out.println("├─────────────────────┤");
        
        if (items.isEmpty()) {
            System.out.println("│  アイテムなし       │");
        } else {
            for (Map.Entry<String, Integer> entry : items.entrySet()) {
                System.out.printf("│  %-12s x%-3d │%n", entry.getKey(), entry.getValue());
            }
        }
        
        System.out.println("└─────────────────────┘");
        System.out.println("種類: " + items.size() + " / " + maxCapacity);
    }
}

パーティ管理クラス

PartyManager.java
package com.javaquest.manager;

import java.util.ArrayList;
import java.util.List;

import com.javaquest.model.Player;

/**
 * パーティ管理クラス
 * 
 * 💡 何をするクラス?
 * → パーティメンバー全員を管理する名簿
 *  (追加、削除、検索、一覧表示)
 * 
 * 💡 身近な例
 * → クラスの出席簿 or LINE グループの管理
 *  「メンバー追加」「メンバー削除」「誰がいるか確認」
 * 
 * 💡 ArrayList を使う理由
 * → メンバーの人数が変わるから!
 *  配列 Player[4] だと4人固定で増やせない
 *  ArrayList なら自由に追加・削除できる
 */
public class PartyManager {
    private List<Player> party;
    private int maxSize;
    
    public PartyManager(int maxSize) {
        this.party = new ArrayList<>();
        this.maxSize = maxSize;
    }
    
    // メンバー追加
    public boolean addMember(Player player) {
        if (party.size() >= maxSize) {
            System.out.println("❌ パーティが満員です");
            return false;
        }
        party.add(player);
        System.out.println("✅ " + player.getName() + " が加わった!");
        return true;
    }
    
    // メンバー削除
    public boolean removeMember(String name) {
        for (Player p : party) {
            if (p.getName().equals(name)) {
                party.remove(p);
                System.out.println("💨 " + name + " が離脱した");
                return true;
            }
        }
        System.out.println("❌ " + name + " が見つかりません");
        return false;
    }
    
    // メンバー検索
    public Player findMember(String name) {
        for (Player p : party) {
            if (p.getName().equals(name)) {
                return p;
            }
        }
        return null;
    }
    
    // レベルアップ
    public boolean levelUpMember(String name) {
        Player p = findMember(name);
        if (p != null) {
            p.levelUp();
            return true;
        }
        System.out.println("❌ " + name + " が見つかりません");
        return false;
    }
    
    // パーティ表示
    public void showParty() {
        System.out.println("\n=== パーティメンバー ===");
        if (party.isEmpty()) {
            System.out.println("  メンバーなし");
            return;
        }
        for (int i = 0; i < party.size(); i++) {
            System.out.println("  [" + (i + 1) + "] " + party.get(i));
        }
        System.out.println("メンバー数: " + party.size() + " / " + maxSize);
    }
    
    // 統計表示
    public void showPartyStats() {
        System.out.println("\n=== パーティ統計 ===");
        if (party.isEmpty()) {
            System.out.println("  メンバーなし");
            return;
        }
        
        int totalHp = 0;
        int totalLevel = 0;
        for (Player p : party) {
            totalHp += p.getHp();
            totalLevel += p.getLevel();
        }
        
        System.out.println("メンバー数: " + party.size());
        System.out.println("総HP: " + totalHp);
        System.out.println("平均レベル: " + (totalLevel / party.size()));
    }
}

Step 3: RPGSystem - ArrayListテストシステム

RPGSystem.java(テスト用)

RPGSystem.java
package com.javaquest;

import java.util.ArrayList;
import java.util.List;

import com.javaquest.manager.PartyManager;
import com.javaquest.model.Inventory;
import com.javaquest.model.Player;

/**
 * RPGシステム(メインクラス)
 * 
 * 💡 何をするクラス?
 * → Player、PartyManager、Inventory を
 *  実際に動かしてデモする
 * 
 * 💡 実行すると?
 * 1. ArrayList の基本操作デモ
 * 2. パーティ管理デモ(追加・削除・レベルアップ)
 * 3. インベントリデモ(アイテム入手・使用)
 * 
 * 💡 学習のポイント
 * → ArrayList を使えば、配列の「サイズ固定」問題を解決!
 *  ゲーム開発では必須の技術
 */
public class RPGSystem {
    
    public static void main(String[] args) {
        RPGSystem system = new RPGSystem();
        
        // ArrayList基本デモ
        system.testArrayListBasics();
        
        // パーティ管理デモ
        system.testPartyManager();
        
        // インベントリデモ
        system.testInventory();
    }
    
    // ArrayList基本操作
    public void testArrayListBasics() {
        System.out.println("=== ArrayList 基本操作 ===\n");
        
        List<String> items = new ArrayList<>();
        
        // 追加
        items.add("ポーション");
        items.add("エリクサー");
        items.add("フェニックスの尾");
        System.out.println("アイテムリスト: " + items);
        
        // 取得
        System.out.println("最初のアイテム: " + items.get(0));
        
        // 削除
        items.remove("エリクサー");
        System.out.println("削除後: " + items);
        
        // 走査
        System.out.println("\n全アイテム:");
        for (String item : items) {
            System.out.println("  - " + item);
        }
    }
    
    // パーティ管理
    public void testPartyManager() {
        System.out.println("\n\n=== パーティ管理 ===\n");
        
        PartyManager manager = new PartyManager(4);
        
        // メンバー追加
        manager.addMember(new Player("勇者アレン", 150, 5, "勇者"));
        manager.addMember(new Player("戦士ベルン", 180, 8, "戦士"));
        manager.addMember(new Player("魔法使いクレア", 100, 3, "魔法使い"));
        manager.addMember(new Player("僧侶ダイアン", 120, 4, "僧侶"));
        
        manager.showParty();
        manager.showPartyStats();
        
        // メンバー検索
        System.out.println("\n【メンバー検索】");
        Player found = manager.findMember("戦士ベルン");
        if (found != null) {
            System.out.println("✅ 見つかった: " + found);
        }
        
        // レベルアップ
        System.out.println("\n【レベルアップ】");
        manager.levelUpMember("魔法使いクレア");
        
        // メンバー削除
        System.out.println("\n【メンバー削除】");
        manager.removeMember("戦士ベルン");
        manager.showParty();
    }
    
    // インベントリ
    public void testInventory() {
        System.out.println("\n\n=== インベントリ ===\n");
        
        Inventory inv = new Inventory(10);
        
        // アイテム追加
        inv.addItem("ポーション", 5);
        inv.addItem("エリクサー", 2);
        inv.addItem("フェニックスの尾", 1);
        
        inv.showInventory();
        
        // アイテム使用
        System.out.println("\n【アイテム使用】");
        inv.useItem("ポーション", 2);
        
        inv.showInventory();
    }
}

実行結果

=== ArrayList 基本操作 ===

アイテムリスト: [ポーション, エリクサー, フェニックスの尾]
最初のアイテム: ポーション
削除後: [ポーション, フェニックスの尾]

全アイテム:
  - ポーション
  - フェニックスの尾


=== パーティ管理 ===

✅ 勇者アレン が加わった!
✅ 戦士ベルン が加わった!
✅ 魔法使いクレア が加わった!
✅ 僧侶ダイアン が加わった!

=== パーティメンバー ===
  [1] 勇者アレン [勇者] Lv.5 HP:150
  [2] 戦士ベルン [戦士] Lv.8 HP:180
  [3] 魔法使いクレア [魔法使い] Lv.3 HP:100
  [4] 僧侶ダイアン [僧侶] Lv.4 HP:120
メンバー数: 4 / 4

=== パーティ統計 ===
メンバー数: 4
総HP: 550
平均レベル: 5

【メンバー検索】
✅ 見つかった: 戦士ベルン [戦士] Lv.8 HP:180

【レベルアップ】
🎉 魔法使いクレア がレベルアップ! Lv.4

【メンバー削除】
💨 戦士ベルン が離脱した

=== パーティメンバー ===
  [1] 勇者アレン [勇者] Lv.5 HP:150
  [2] 魔法使いクレア [魔法使い] Lv.4 HP:100
  [3] 僧侶ダイアン [僧侶] Lv.4 HP:120
メンバー数: 3 / 4


=== インベントリ ===

✅ ポーション を 5 個入手(合計: 5)
✅ エリクサー を 2 個入手(合計: 2)
✅ フェニックスの尾 を 1 個入手(合計: 1)

┌─────────────────────┐
│   🎒 インベントリ   │
├─────────────────────┤
│  エリクサー     x2   │
│  ポーション     x5   │
│  フェニックスの尾  x1 │
└─────────────────────┘
種類: 3 / 10

【アイテム使用】
✅ ポーション を 2 個使用(残り: 3)

┌─────────────────────┐
│   🎒 インベントリ   │
├─────────────────────┤
│  エリクサー     x2   │
│  ポーション     x3   │
│  フェニックスの尾  x1 │
└─────────────────────┘
種類: 3 / 10

練習問題

練習1: ArrayList の基本操作

問題: 以下の要件を満たすコードを書いてください。

  1. 文字列のArrayListを作成
  2. "剣", "盾", "弓", "杖" を追加
  3. "弓" を削除
  4. すべての要素を表示
解答例
package practice;

import java.util.ArrayList;
import java.util.List;

public class Practice01 {
    public static void main(String[] args) {
        // 1. ArrayListを作成
        List<String> weapons = new ArrayList<>();
        
        // 2. 要素を追加
        weapons.add("剣");
        weapons.add("盾");
        weapons.add("弓");
        weapons.add("杖");
        
        // 3. "弓"を削除
        weapons.remove("弓");
        
        // 4. すべての要素を表示
        System.out.println("武器一覧: " + weapons);
        
        // for文での表示
        for (String weapon : weapons) {
            System.out.println("- " + weapon);
        }
    }
}

実行結果:

武器一覧: [剣, 盾, 杖]
- 剣
- 盾
- 杖

練習2: ArrayList の実践練習

問題: RPGゲームのアイテム管理システムを作成してください。

要求:

  1. String型のArrayListで所持アイテムを管理
  2. 「回復薬」「マナポーション」「鉄の剣」「盾」「パン」を追加
  3. 「鉄の剣」を使用(リストから削除)
  4. アイテム数と最初のアイテムを表示
  5. 全アイテムを一覧表示
解答例
package practice;

import java.util.ArrayList;

public class ItemManager {
    public static void main(String[] args) {
        // 1. ArrayListでアイテムを管理
        ArrayList<String> inventory = new ArrayList<>();
        
        // 2. アイテムを追加
        inventory.add("回復薬");
        inventory.add("マナポーション");
        inventory.add("鉄の剣");
        inventory.add("盾");
        inventory.add("パン");
        System.out.println("🎒 アイテムを収集しました!");
        
        // 3. 鉄の剣を使用(削除)
        boolean used = inventory.remove("鉄の剣");
        if (used) {
            System.out.println("⚔️ 鉄の剣で攻撃!");
        }
        
        // 4. アイテム数と最初のアイテムを表示
        System.out.println("🎒 所持アイテム数: " + inventory.size());
        if (!inventory.isEmpty()) {
            System.out.println("🥇 最初のアイテム: " + inventory.get(0));
        }
        
        // 5. 全アイテム一覧
        System.out.println("\n=== 所持アイテム一覧 ===");
        for (int i = 0; i < inventory.size(); i++) {
            System.out.println((i + 1) + ". " + inventory.get(i));
        }
    }
}

実行結果:

🎒 アイテムを収集しました!
⚔️ 鉄の剣で攻撃!
🎒 所持アイテム数: 4
🥇 最初のアイテム: 回復薬

=== 所持アイテム一覧 ===
1. 回復薬
2. マナポーション
3. 盾
4. パン

練習3: ArrayList でソート機能

問題: プレイヤーのレベルでソートする機能を作成してください。

要求:

  1. PlayerオブジェクトのArrayListを作成
  2. 5人のプレイヤーを追加(異なるレベル)
  3. バブルソートでレベルの高い順に並び替え
  4. ソート結果を表示
解答例
package practice;

import java.util.ArrayList;

// 簡単なPlayerクラス
class SortablePlayer {
    private String name;
    private int level;
    
    public SortablePlayer(String name, int level) {
        this.name = name;
        this.level = level;
    }
    
    public String getName() { return name; }
    public int getLevel() { return level; }
    
    @Override
    public String toString() {
        return name + "(Lv." + level + ")";
    }
}

public class PlayerSorting {
    public static void main(String[] args) {
        // 1. プレイヤーリストを作成
        ArrayList<SortablePlayer> players = new ArrayList<>();
        
        // 2. プレイヤーを追加
        players.add(new SortablePlayer("勇者", 15));
        players.add(new SortablePlayer("戦士", 12));
        players.add(new SortablePlayer("魔法使い", 18));
        players.add(new SortablePlayer("僧侶", 10));
        players.add(new SortablePlayer("盗賊", 14));
        
        System.out.println("=== ソート前 ===");
        for (SortablePlayer p : players) {
            System.out.println(p);
        }
        
        // 3. レベルの高い順でソート(バブルソート)
        // 高校生にも分かりやすい方法でソートします
        System.out.println("🔄 ソート中...");
        
        // 外側のループ: 何度も繰り返して並び替える
        for (int i = 0; i < players.size() - 1; i++) {
            // 内側のループ: 隣同士を比較して交換
            for (int j = 0; j < players.size() - 1 - i; j++) {
                // 左側のプレイヤーのレベルが低い場合、交換する
                if (players.get(j).getLevel() < players.get(j + 1).getLevel()) {
                    // 2つの要素を交換(バブルソートの基本操作)
                    SortablePlayer temp = players.get(j);     // 一時保存
                    players.set(j, players.get(j + 1));       // 右を左に
                    players.set(j + 1, temp);                 // 左を右に
                }
            }
        }
        
        // 🔥 ボーナス: モダンなJavaの書き方(参考)
        // 上記のバブルソートの代わりに、1行で書けます!
        // players.sort((a, b) -> b.getLevel() - a.getLevel());
        
        // 4. ソート結果を表示
        System.out.println("\n=== レベル順ランキング ===");
        for (int i = 0; i < players.size(); i++) {
            String medal = "";
            if (i == 0) medal = "🥇";      // 1位は金メダル
            else if (i == 1) medal = "🥈"; // 2位は銀メダル
            else if (i == 2) medal = "🥉"; // 3位は銅メダル
            else medal = "  ";             // 4位以下は空白
            
            System.out.println(medal + " " + (i + 1) + "位: " + players.get(i));
        }
    }
}

実行結果

=== ソート前 ===
勇者(Lv.15)
戦士(Lv.12)
魔法使い(Lv.18)
僧侶(Lv.10)
盗賊(Lv.14)

🔄 ソート中...

=== レベル順ランキング ===
🥇 1位: 魔法使い(Lv.18)
🥈 2位: 勇者(Lv.15)
🥉 3位: 盗賊(Lv.14)
   4位: 戦士(Lv.12)
   5位: 僧侶(Lv.10)

バブルソートの仕組み

バブルソートは隣同士を比較して交換を繰り返すソート方法です。

  1. 比較: 隣の2つを比較 → players.get(j) vs players.get(j+1)
  2. 交換: 順番が違う場合は位置を入れ替える
  3. 繰り返し: 全体が整列されるまで繰り返す

メリット: 理解しやすい、小さなデータに適している
デメリット: 大きなデータは遅い

現代のJavaではもっと簡単!

上記のバブルソートは 学習目的 ですが、実際のJava開発では1行で書けます:

// 🔥 モダンなJava(1行でソート!)
players.sort((a, b) -> b.getLevel() - a.getLevel());

// または(少し詳しく書く場合)
players.sort(Comparator.comparing(SortablePlayer::getLevel).reversed());

比較してみましょう

方法 コード行数 理解しやすさ 実用性
バブルソート 10行+ ⭐⭐⭐ 学習用
ラムダ式 1行 ⭐⭐ 実務標準
メソッド参照 1行 上級者向け

学習の流れ

  1. まず基本を理解 → バブルソートでソートの仕組みを学ぶ
  2. 実務では効率重視 → ラムダ式で1行で書く
  3. さらに上達 → メソッド参照でより簡潔に

まとめ

今回学んだこと

1. ArrayList - 可変長リスト

List<String> list = new ArrayList<>();
list.add("要素");          // 追加
String item = list.get(0); // 取得
list.remove("要素");       // 削除
int size = list.size();    // サイズ

メリット:

  • サイズが自動で拡張
  • 豊富なメソッド
  • 型安全(ジェネリクス)

2. ソートの進歩 - 基本からモダンまで

基本編 (学習目的)

// バブルソート(10行+)
for (int i = 0; i < players.size() - 1; i++) {
    for (int j = 0; j < players.size() - 1 - i; j++) {
        if (players.get(j).getLevel() < players.get(j + 1).getLevel()) {
            // 交換処理...
        }
    }
}

モダン編 (実務用)

// ラムダ式(1行!)
players.sort((a, b) -> b.getLevel() - a.getLevel());

進歩のポイント

  • 理解しやすさ: バブルソートで基礎を学ぶ
  • 効率性: ラムダで短時間で実装
  • 実用性: 現実の開発で使える技術

3. コレクションの選び方

用途 推奨コレクション 理由
順序ありリスト ArrayList インデックスアクセス、順序保持
重複なしセット HashSet 重複排除、高速検索
キー・値ペア HashMap 第4回で学習予定 🚀
ソート済みデータ TreeSet/TreeMap 自動ソート

4. 実務的なポイント

ジェネリクス必須 → 型安全性確保
インターフェース宣言List<T> を使用
適切なコレクション選択 → 用途に応じて選択
モダンな書き方を学ぶ → ラムダ、Stream APIなど

5. Javaの進歩を実感

学習ステップ

  1. 基礎理解 → バブルソートでアルゴリズムを理解
  2. 実務適用 → ラムダ式で効率的に実装
  3. 更なる上達 → Stream API、メソッド参照など

今後の期待

  • 第5回: 文字列処理でString.formatの威力を体験
  • 第6回: CSV処理でデータ連携の楽しさを実感
  • 第8回: 全機能統合でJavaの完成形を体験

次回予告

第4回:HashMapでキー・値ペアのデータを管理しよう!

// 第3回までの処理(ArrayList)
ArrayList<Player> party = new ArrayList<>();
for (Player player : party) {
    if (player.getJob().equals("戦士")) {
        System.out.println("戦士を発見:" + player.getName());
    }
}

// 第4回で学ぶ処理(HashMap)
Map<String, Player> partyMap = new HashMap<>();
partyMap.put("リーダー", warrior);
partyMap.put("サブ", mage);

// 直接アクセスで高速!
Player leader = partyMap.get("リーダー");

学習内容:

  • HashMap の基本操作(put/get/remove)
  • キーと値のペア管理
  • スキル辞書、アイテム図鑑の作成
  • ArrayList vs HashMap の使い分け

📚 参考資料


関連記事

第1回:ファイル入出力でセーブ・ロード機能を作ろう!
第2回:例外処理でセーブシステムを堅牢にしよう!

  • 次回: HashMapでキー・値ペアのデータを管理

本記事は教育目的で作成されています。RPGの例を通じてプログラミング概念を楽しく学習できることを目指しています。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?