Java / LESSON 12 / JV12

Java:List と Map

1学習の目的

2基礎解説

配列は長さを先に決める必要があり、後から変えられません。実際のデータは何件になるか分からないことが多く、そこで使うのが List です。

配列ListMap
長さ固定自由に増減自由に増減
取り出しa[0]list.get(0)map.get("キー")
件数a.lengthlist.size()map.size()
向いている件数が決まっている順番に並べるキーで検索
✅ 覚えるべき重要ポイント
  1. List<String> list = new ArrayList<>(); が基本形<> の中に入れる型を書く。左辺は List、右辺は ArrayList と書くのが慣習。
  2. 基本型はそのまま入れられないList<int> ではなく List<Integer> と書く。int → Integer、double → Double のようにラッパークラスを使う。
  3. map.get() は見つからないと null を返す。そのまま計算に使うとエラーになるので、getOrDefault() で既定値を指定するのが安全。
  4. List.of() で作ったリストは変更できないadd しようとすると例外が出る。変更したいなら new ArrayList<>(List.of(…)) と包む。
  5. HashMap は順序が保証されない。並び順が必要なら TreeMap(キー順)や LinkedHashMap(挿入順)を使う。

現場使用例:検索結果の一覧(List)、商品コードから商品を引く(Map)、集計処理、設定値の管理。実務のJavaでは配列よりList・Mapのほうが圧倒的に多く使われる

import java.util.*;    // List, Map などをまとめて読み込む

// ① List(順番に並べる)
List<String> items = new ArrayList<>();
items.add("ノートPC");
items.add("マウス");

items.get(0);              // "ノートPC"
items.size();              // 2
items.remove(0);           // 0番目を削除
items.contains("マウス");   // true
items.indexOf("マウス");    // 0(無ければ -1)

for (String item : items) { … }

// 基本型は ラッパークラス で
List<Integer> nums = new ArrayList<>(List.of(30, 10, 20));
Collections.sort(nums);          // [10, 20, 30]
Collections.reverse(nums);       // [30, 20, 10]
Collections.max(nums);           // 30

// ⚠ List.of は変更できない
List<String> fixed = List.of("A", "B");
// fixed.add("C");   → 例外が出る

// ② Map(キーと値のペア)
Map<String, Integer> stock = new HashMap<>();
stock.put("ノートPC", 5);
stock.put("マウス", 42);

stock.get("マウス");                    // 42
stock.get("存在しない");                 // null ⚠
stock.getOrDefault("存在しない", 0);      // 0 ← 安全
stock.containsKey("ノートPC");           // true

// Map のループ
for (Map.Entry<String, Integer> e : stock.entrySet()) {
    System.out.println(e.getKey() + "=" + e.getValue());
}

// ⭐ 集計の定番パターン
Map<String, Integer> count = new TreeMap<>();
for (String d : data) {
    count.put(d, count.getOrDefault(d, 0) + 1);
}

3基本ドリル(10問)

JV12-D01 List を作って3件追加し、件数と最初の要素を出力せよ(2行)。 コーディング★☆☆無料
期待される結果

出力2行。3 / ノートPC

ヒント

List list = new ArrayList<>(); で作り、add で追加する。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> items = new ArrayList<>();
        items.add("ノートPC");
        items.add("マウス");
        items.add("キーボード");

        System.out.println(items.size());
        System.out.println(items.get(0));
    }
}
解説

長さを先に決めなくてよいのがListの利点。何件になるか分からないデータを扱うときに必須になる。

JV12-D02 List に整数を入れるときの正しい書き方はどれか。
A. List<int> B. List<Integer> C. List<number> D. List<Int>
選択★☆☆無料
期待される結果

解答 == B

ヒント

基本型ではなくラッパークラスを使う。

模範解答
B
解説

List には基本型を直接入れられない。int → Integer、double → Double、boolean → Boolean と対応するクラスを使う。

JV12-D03 Map を作って2件登録し、キー「マウス」で値を取り出して出力せよ。 コーディング★☆☆無料
期待される結果

出力 == 42

ヒント

Map map = new HashMap<>(); で作り、put で登録する。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> stock = new HashMap<>();
        stock.put("ノートPC", 5);
        stock.put("マウス", 42);

        System.out.println(stock.get("マウス"));
    }
}
解説

Map はキーで一発検索できる。Listなら全件ループして探すところを、1行で取り出せる。

JV12-D04 Listに要素を追加するメソッドを補ってコードを完成させよ。 穴埋め★☆☆無料
コード
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.____("テスト");

        System.out.println(list.get(0));
    }
}
期待される結果

出力 == テスト

ヒント

「加える」を意味する3文字のメソッド。

模範解答
add
解説

add で末尾に追加される。位置を指定したいなら add(0, "値") のように添字を渡す。

JV12-D05 map.get("存在しないキー") の結果はどれか。
A. 0 B. null C. 空文字 D. エラー
選択★☆☆無料
期待される結果

解答 == B

ヒント

見つからないときの戻り値。

模範解答
B
解説

null が返るので、そのまま計算に使うとエラーになるgetOrDefault で既定値を指定するのが安全。

JV12-D06 getOrDefault を使い、存在しないキーでも安全に値を取得せよ(既定値0を指定し、0を出力すること)。 コーディング★★☆広告解放
期待される結果

出力 == 0

ヒント

map.getOrDefault("キー", 0) と書く。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> stock = new HashMap<>();
        stock.put("ノートPC", 5);

        System.out.println(stock.getOrDefault("存在しない商品", 0));
    }
}
解説

null チェックが不要になる。「無ければ0」という前提が明確なら、この書き方のほうが短く安全。

JV12-D07 Listを並べ替えるコードを完成させよ。 穴埋め★★☆広告解放
コード
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<Integer> nums = new ArrayList<>(List.of(30, 10, 20));

        Collections.____(nums);

        System.out.println(nums);
    }
}
期待される結果

出力 == [10, 20, 30]

ヒント

「並べ替える」を意味する4文字のメソッド。

模範解答
sort
解説

Collections.sort は元のリストを並べ替える。配列の Arrays.sort と対になる存在。

JV12-D08 List.of("A", "B") で作ったリストに add するとどうなるか。
A. 追加される B. 例外が出る C. 無視される D. コンパイルエラー
選択★★☆広告解放
期待される結果

解答 == B

ヒント

List.of は変更できないリストを作る。

模範解答
B
解説

UnsupportedOperationException が出る。変更したいなら new ArrayList<>(List.of(…)) と包む必要がある。

JV12-D09 Map をループして全件を「ノートPC=5」の形式で出力せよ(キー順に並べるため TreeMap を使うこと)。 コーディング★★☆広告解放
期待される結果

出力2行。ノートPC=5 / マウス=42

ヒント

for (Map.Entry e : map.entrySet()) を使う。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> stock = new TreeMap<>();
        stock.put("マウス", 42);
        stock.put("ノートPC", 5);

        for (Map.Entry<String, Integer> e : stock.entrySet()) {
            System.out.println(e.getKey() + "=" + e.getValue());
        }
    }
}
解説

TreeMap はキー順に並ぶ。HashMap では順序が保証されないので、出力順が実行ごとに変わる可能性がある。

JV12-D10 Listから要素を削除し、削除後のリストを出力せよ(3件中の1番目を削除)。 コーディング★★☆広告解放
期待される結果

出力 == [ノートPC, キーボード]

ヒント

remove(1) で添字1の要素を削除する。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> items = new ArrayList<>(
                List.of("ノートPC", "マウス", "キーボード"));

        items.remove(1);

        System.out.println(items);
    }
}
解説

削除すると後ろの要素が詰まる。配列なら固定長なので、こうした操作は自分で書く必要があった。

4実践シナリオ(5問)

JV12-S01 【動的な商品リスト】空のListに3件追加し、4文字以下のものだけを新しいListに集めて出力せよ(ノートPC・マウス・モニターの3件)。 コーディング★★☆広告解放
期待される結果

出力 == [マウス, モニター]

ヒント

ループしながら条件判定し、別のリストに add する。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        List<String> items = new ArrayList<>();
        items.add("ノートPC");
        items.add("マウス");
        items.add("モニター");

        List<String> shortNames = new ArrayList<>();
        for (String item : items) {
            if (item.length() <= 4) {
                shortNames.add(item);
            }
        }

        System.out.println(shortNames);
    }
}
解説

マウス(3文字)とモニター(4文字)が該当し、ノートPC(5文字)は除外される。何件該当するか分からなくてもListなら書ける——配列では「最大何件か」を先に決める必要があった。

JV12-S02 【出現回数の集計】配列 {"A", "B", "A", "C", "A"} の出現回数を Map で集計し、キー順に出力せよ(TreeMap)。 コーディング★★☆広告解放
期待される結果

出力 == {A=3, B=1, C=1}

ヒント

map.put(key, map.getOrDefault(key, 0) + 1) が集計の定番。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        String[] data = {"A", "B", "A", "C", "A"};

        Map<String, Integer> count = new TreeMap<>();
        for (String d : data) {
            count.put(d, count.getOrDefault(d, 0) + 1);
        }

        System.out.println(count);
    }
}
解説

この1行が集計の定番パターン。初回は getOrDefault が0を返し、2回目以降は既存の値に足される。

JV12-S03 【在庫の検索】商品名→在庫数のMapを作り、存在する商品と存在しない商品の両方を安全に検索して2行出力せよ(無い場合は0)。 コーディング★★☆広告解放
期待される結果

出力2行。5 / 0

ヒント

getOrDefault を使えば null チェックが不要。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> stock = new HashMap<>();
        stock.put("ノートPC", 5);
        stock.put("マウス", 42);

        System.out.println(stock.getOrDefault("ノートPC", 0));
        System.out.println(stock.getOrDefault("キーボード", 0));
    }
}
解説

Mapなら全件ループせずに検索できる。データが1万件あっても、取り出す速度はほとんど変わらない。

JV12-S04 【オブジェクトのList】Product クラスを作り、Listに3件入れて在庫金額の合計を出力せよ(ノートPC/128000/5、マウス/3200/42、キーボード/8500/18)。 コーディング★★★広告解放
期待される結果

出力 == 927400

ヒント

List を作り、拡張forで合計する。

模範解答
import java.util.*;

public class Main {

    static class Product {
        String name;
        int price;
        int stock;

        Product(String name, int price, int stock) {
            this.name = name;
            this.price = price;
            this.stock = stock;
        }

        int stockValue() {
            return price * stock;
        }
    }

    public static void main(String[] args) {
        List<Product> items = new ArrayList<>();
        items.add(new Product("ノートPC", 128000, 5));
        items.add(new Product("マウス", 3200, 42));
        items.add(new Product("キーボード", 8500, 18));

        int total = 0;
        for (Product p : items) {
            total += p.stockValue();
        }

        System.out.println(total);
    }
}
解説

ListにはどんなクラスでもDefault入れられる。自分で作ったクラスも、標準のクラスと同じように扱える。

JV12-S05 【カテゴリ別の集計】商品名→カテゴリのMapから、カテゴリごとの件数を集計して出力せよ(PC系2件、周辺機器1件)。 コーディング★★★広告解放
期待される結果

出力 == {PC=2, 周辺機器=1}

ヒント

値をキーにして数える。TreeMap で順序を固定する。

模範解答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, String> category = new LinkedHashMap<>();
        category.put("ノートPC", "PC");
        category.put("デスクトップ", "PC");
        category.put("マウス", "周辺機器");

        Map<String, Integer> count = new TreeMap<>();
        for (String c : category.values()) {
            count.put(c, count.getOrDefault(c, 0) + 1);
        }

        System.out.println(count);
    }
}
解説

values() で値だけを取り出せる。キーが必要なら keySet()、両方なら entrySet() を使い分ける。

5仕上げ課題

JV12-FINAL 【注文集計システム】List と Map を組み合わせて、注文データを集計せよ。

Product クラス:name・category・price(getterまたは直接アクセス可)

データ(List<Product> に格納)
・ノートPC / PC / 128000
・デスクトップ / PC / 98000
・マウス / 周辺機器 / 3200
・キーボード / 周辺機器 / 8500
・モニター / 周辺機器 / 45000

処理
① 全商品を「1. ノートPC(PC):128,000円」の形式で出力
カテゴリ別の合計金額を Map で集計し、キー順に「PC:226,000円」の形式で出力
カテゴリ別の件数も同時に集計し、「PC:2件」の形式で出力
④ 全体の合計金額を出力

期待される出力(10行)
1. ノートPC(PC):128,000円
2. デスクトップ(PC):98,000円
3. マウス(周辺機器):3,200円
4. キーボード(周辺機器):8,500円
5. モニター(周辺機器):45,000円
---
PC:226,000円(2件)
周辺機器:56,700円(3件)
---
合計:282,700円
総合★★★広告解放
期待される結果

出力10行が完全一致

ヒント

カテゴリ別の集計には Map を2つ(金額用と件数用)用意する。TreeMap を使えばキー順に並ぶ。getOrDefault で初回を0として扱う。

模範解答
import java.util.*;

public class Main {

    static class Product {
        String name;
        String category;
        int price;

        Product(String name, String category, int price) {
            this.name = name;
            this.category = category;
            this.price = price;
        }
    }

    public static void main(String[] args) {
        List<Product> items = new ArrayList<>();
        items.add(new Product("ノートPC", "PC", 128000));
        items.add(new Product("デスクトップ", "PC", 98000));
        items.add(new Product("マウス", "周辺機器", 3200));
        items.add(new Product("キーボード", "周辺機器", 8500));
        items.add(new Product("モニター", "周辺機器", 45000));

        Map<String, Integer> sumByCategory = new TreeMap<>();
        Map<String, Integer> countByCategory = new TreeMap<>();

        int total = 0;

        for (int i = 0; i < items.size(); i++) {
            Product p = items.get(i);

            System.out.println((i + 1) + ". " + p.name + "(" + p.category + "):"
                    + String.format("%,d", p.price) + "円");

            sumByCategory.put(p.category,
                    sumByCategory.getOrDefault(p.category, 0) + p.price);
            countByCategory.put(p.category,
                    countByCategory.getOrDefault(p.category, 0) + 1);

            total += p.price;
        }

        System.out.println("---");

        for (Map.Entry<String, Integer> e : sumByCategory.entrySet()) {
            String cat = e.getKey();
            System.out.println(cat + ":" + String.format("%,d", e.getValue())
                    + "円(" + countByCategory.get(cat) + "件)");
        }

        System.out.println("---");
        System.out.println("合計:" + String.format("%,d", total) + "円");
    }
}
解説

この集計は、配列だけでは非常に書きにくい。「カテゴリが何種類あるか」が事前に分からないからだ。配列で書くなら、まず全件走査してカテゴリの一覧を作り、その数だけ配列を確保し、それから集計する——3周も必要になる。Map なら1周で済む。

sumByCategory.getOrDefault(p.category, 0) + p.price が集計の核心だ。初めて登場したカテゴリなら0から、2回目以降は既存の値に足す——この1行が、カテゴリの種類を意識せずに集計を成立させている。もし get() を使っていたら、初回は null が返って null + p.price でエラーになっていた。

TreeMap を選んだ理由も明確だ。HashMap では出力順が保証されないため、実行するたびに「PC」と「周辺機器」の順序が入れ替わる可能性がある。テストで期待値と比較するような場面では、これが不具合として現れる。

実務のJavaでは、配列よりも List と Map のほうが圧倒的に多く使われる。件数が動的に変わり、キーで検索する必要があるのが現実のデータだからだ。配列は「サイズが固定で高速性が要る場面」に限られる。

次章では例外処理を学ぶ。ここまで try/catch を断片的に使ってきたが、エラーとどう向き合うかを体系的に扱う。