MENU

【Java】レッスン4-04:TreeMapの使い方とHashMapとの違いをマスターしよう

tggaa478@yahoo.co.jp

一つ前のページではHashMapについて学習しました。

今回は TreeMap について見ていきましょう。

Lesson1:基礎文法編
Lesson2:制御構造編
Lesson3:メソッド編
Lesson4:コレクション編

 ・Lesson4-1:ArrayListを理解しよう
 ・Lesson4-2:HashSetとTreeSetを理解しよう
 ・Lesson4-3:HashMapを理解しよう
 ・Lesson4-4:TreeMapを理解しよう ◁今回はココ
 ・確認問題4-☆1:ナインゲームを作ろう
 ・確認問題4-☆2:アラビア数字をローマ数字に変換するアプリを作ろう
Lesson5:クラス

<<前のページ

学習記事一覧

次のページ>>

JavaのTreeMapとは?|キーで自動ソートされるMapの基本を解説

Javaでプログラミングを始めたばかりの方にとって、データ構造を正しく理解することは非常に重要です。

その中でもJavaのコレクションフレームワークに含まれる「TreeMap」は、データを効率的に格納し、検索するために使える便利なクラスです。

本記事ではTreeMapの基本的な使い方を説明し、後半ではよく比較されるHashMapとの違いについても詳しく解説します。

TreeMapの仕組み|内部構造と自動ソートの仕組みを理解しよう

TreeMapはJavaのjava.utilパッケージに含まれるクラスで、キーと値のペア(key-value pair)を保持するマップの一種です。

TreeMapの特徴はキーが自動的にソートされることです。これは内部で赤黒木(Red-Black Tree)というバランスの取れた二分探索木を使っているためです。

そのためTreeMapを使用すると要素を挿入した順番ではなく、キーの自然順序(またはComparatorを使ったカスタム順序)に基づいてソートされます。

TreeMapの使い方入門|要素の追加・取得・表示を学ぼう

それでは基本的なTreeMapの使い方を見てみましょう。

import java.util.TreeMap; // TreeMapを使用するためのインポート文

public class TreeMapExample {
    public static void main(String[] args) {
        //Int型のキーとString型の値をもつtreeMapというTreeMapを作成
        TreeMap<Integer, String> treeMap = new TreeMap<>();

        // putメソッドを使って要素を追加
        treeMap.put(3, "三");
        treeMap.put(1, "一");
        treeMap.put(2, "二");

        // 要素の表示
        System.out.println("TreeMapの内容: " + treeMap);

        // getメソッドを使って特定のキーの値を取得
        System.out.println("キー1の値: " + treeMap.get(1));

        // ソートされたキーの一覧を取得
        System.out.println("ソートされたキー: " + treeMap.keySet());
    }
}

このコードを実行すると以下のような結果が得られます:

TreeMapの内容: {1=一, 2=二, 3=三}
キー1の値: 一
ソートされたキー: [1, 2, 3]

TreeMapではキーが自動的にソートされているため、put()メソッドで値を挿入した順番とは異なり、キーが昇順で並び替えられています。

TreeMapで使える主要メソッド一覧と使い方解説

TreeMapは以下のような便利なメソッドを提供しています。

  • put(K key, V value): キーと値のペアをマップに挿入します。
  • get(Object key): 指定したキーに対応する値を返します。
  • remove(Object key): 指定したキーに対応するエントリを削除します。
  • firstKey(): 最小のキーを返します。
  • lastKey(): 最大のキーを返します。
  • size(): TreeMapに含まれるエントリの数を返します。

TreeMapとHashMapの違いを徹底比較|パフォーマンスやnullの扱いなど

TreeMapとよく比較されるのがHashMapです。どちらもキーと値のペアを保持するマップですが、それぞれ特徴が異なります。

ここでは両者の違いを簡単にまとめます。

特徴TreeMapHashMap
ソート順キーが自然順序またはComparatorでソートされる挿入順序は保証されない
内部構造赤黒木を使用ハッシュテーブルを使用
パフォーマンスデータの挿入・削除にO(log n)の時間がかかるO(1)に近い時間で操作が可能
nullの扱いnullキーは許可されないnullキーとnull値の両方が許可される
主な用途データをソートされた状態で保持したいとき高速なデータ挿入と取得が必要なとき

TreeMapかHashMapか?目的別に最適なMapを選ぶ方法

  • データを順序通りに保持したい場合:キーのソートが必要な場面、例えば数値やアルファベット順で要素を処理したいときには、TreeMapが適しています。
  • 高速なデータ操作が必要な場合:順序を気にせず、挿入や検索をできるだけ早く行いたいときは、HashMapを使用する方が効果的です。

例えばアルファベット順にユーザーの名前を管理したい場合はTreeMapを使うと便利ですが、単純にユーザーIDと名前を対応させたいだけなら、HashMapの方が効率的でしょう。

練習問題|TreeMapとHashMapの違いを理解して使い分けよう

あなたは学校の教師で、生徒のテストの点数を管理するプログラムを作成したいと考えています。

生徒の名前とその点数を入力し、それを使って以下の機能を実現するプログラムを作成してください。

この問題の要件

以下の要件に従ってコードを完成させてください。

  • Scannerクラスを使ってユーザーから生徒の名前と点数を3人分入力すること。
  • HashMapを使用して、入力された生徒の名前と点数を格納すること。
  • HashMapの内容を入力順に表示すること。
  • HashMapの内容をTreeMapにコピーし、名前のアルファベット順に並び替えて表示すること。
  • HashMapの内容を表示するメソッドprintHashMapを作成すること。
  • TreeMapの内容を表示するメソッドprintTreeMapを作成すること。

ただし、以下のような実行結果となること。

生徒の名前を入力してください: 田中
田中の点数を入力してください: 85
生徒の名前を入力してください: 鈴木
鈴木の点数を入力してください: 92
生徒の名前を入力してください: 佐藤
佐藤の点数を入力してください: 78
HashMapを使って入力順に記載:
田中の点数は85点です。
鈴木の点数は92点です。
佐藤の点数は78点です。
TreeMapを使って名前のアルファベット順に記載:
佐藤の点数は78点です。
鈴木の点数は92点です。
田中の点数は85点です。

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

Q
ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:HashMapクラスをインポート
2:Scannerクラスをインポート
3:TreeMapクラスをインポート
4:MapExampleクラスの定義
  □ mainメソッドの定義
  □ □ Scannerオブジェクトscannerの初期化
  □ □ HashMapオブジェクトstudentHashMapの初期化
  □ □ forループを3回繰り返すように設定
  □ □ □ 「生徒の名前を入力してください: 」と出力
  □ □ □ ユーザーの入力を文字列として読み取り、変数nameに代入
  □ □ □ 「[name]の点数を入力してください: 」と出力
  □ □ □ ユーザーの入力を整数として読み取り、変数scoreに代入
  □ □ □ 改行を消費するためにscanner.nextLine()を呼び出し
  □ □ □ studentHashMapにnameとscoreを格納
  □ □ TreeMapオブジェクトstudentTreeMapをstudentHashMapから初期化
  □ □ 「HashMapを使って入力順に記載:」と出力
  □ □ printHashMapメソッドを呼び出し、studentHashMapを渡す
  □ □ 「TreeMapを使って名前のアルファベット順に記載:」と出力
  □ □ printTreeMapメソッドを呼び出し、studentTreeMapを渡す
  □ printHashMapメソッドの定義
  □ □ forループでHashMapのkeySetを走査
  □ □ □ nameに対して対応するscoreを取得し、「[name]の点数は[score]点です。」と出力
  □ printTreeMapメソッドの定義
  □ □ forループでTreeMapのkeySetを走査
  □ □ □ nameに対して対応するscoreを取得し、「[name]の点数は[score]点です。」と出力

Q
ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

import java.util.HashMap;
import java.util.Scanner;
import java.util.TreeMap;

public class MapExample {

    // メインメソッド
    public static void main(String[] args) {
        // スキャナを作成してユーザー入力を受け取る
        Scanner scanner = new Scanner(System.in);

        /*【穴埋め問題1】
        ここで生徒の名前と点数を格納するためのHashMapを作成してください。
        */

        // 3人の生徒の情報を入力してもらう
        for (int i = 0; i < 3; i++) {
            System.out.print("生徒の名前を入力してください: ");
            String name = scanner.nextLine();
            System.out.print(name + "の点数を入力してください: ");
            int score = scanner.nextInt();
            scanner.nextLine(); // 改行を消費する

            /*【穴埋め問題2】
            ここでHashMapにnameとscoreを格納してください。
            */
        }

        /*【穴埋め問題3】
        ここで生徒の名前と点数を格納するTreeMapを作成し、先ほどのHashMapを引数にして初期化してください。
        */

        // HashMapの内容を表示
        System.out.println("HashMapを使って入力順に記載:");

        /*【穴埋め問題4】
        ここでprintHashMapメソッドを呼び出し、studentHashMapを引数として渡してください。
        */

        // TreeMapの内容を表示
        System.out.println("TreeMapを使って名前のアルファベット順に記載:");

        /*【穴埋め問題5】
        ここでprintTreeMapメソッドを呼び出し、studentTreeMapを引数として渡してください。
        */
    }

    // HashMapの内容を表示するメソッド
    public static void printHashMap(HashMap<String, Integer> map) {
        // HashMapから名前と点数を一つずつ取り出して表示
        for (String name : map.keySet()) {
            Integer score = map.get(name);
            System.out.println(name + "の点数は" + score + "点です。");
        }
    }

    // TreeMapの内容を表示するメソッド
    public static void printTreeMap(TreeMap<String, Integer> map) {
        // TreeMapから名前と点数を一つずつ取り出して表示
        for (String name : map.keySet()) {
            Integer score = map.get(name);
            System.out.println(name + "の点数は" + score + "点です。");
        }
    }
}

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

練習問題の解答と解説

この問題の正解コードとその解説は以下の通りです。

クリックして開いて確認してください。

Q
正解コード
import java.util.HashMap;
import java.util.Scanner;
import java.util.TreeMap;

public class MapExample {

    // メインメソッド
    public static void main(String[] args) {
        // スキャナを作成してユーザー入力を受け取る
        Scanner scanner = new Scanner(System.in);

        // 生徒の名前と点数を格納するHashMapを作成
        HashMap<String, Integer> studentHashMap = new HashMap<>();

        // 3人の生徒の情報を入力してもらう
        for (int i = 0; i < 3; i++) {
            System.out.print("生徒の名前を入力してください: ");
            String name = scanner.nextLine();
            System.out.print(name + "の点数を入力してください: ");
            int score = scanner.nextInt();
            scanner.nextLine(); // 改行を消費する
            studentHashMap.put(name, score);
        }

        // 生徒の名前と点数を格納するTreeMapを作成
        TreeMap<String, Integer> studentTreeMap = new TreeMap<>(studentHashMap);

        // HashMapの内容を表示
        System.out.println("HashMapを使って入力順に記載:");
        printHashMap(studentHashMap);

        // TreeMapの内容を表示
        System.out.println("TreeMapを使って名前のアルファベット順に記載:");
        printTreeMap(studentTreeMap);
    }

    // HashMapの内容を表示するメソッド
    public static void printHashMap(HashMap<String, Integer> map) {
        // HashMapから名前と点数を一つずつ取り出して表示
        for (String name : map.keySet()) {
            Integer score = map.get(name);
            System.out.println(name + "の点数は" + score + "点です。");
        }
    }

    // TreeMapの内容を表示するメソッド
    public static void printTreeMap(TreeMap<String, Integer> map) {
        // TreeMapから名前と点数を一つずつ取り出して表示
        for (String name : map.keySet()) {
            Integer score = map.get(name);
            System.out.println(name + "の点数は" + score + "点です。");
        }
    }
}
Q
正解コードの解説

コードをブロックごとに分割して解説します。

スキャナの作成

Scanner scanner = new Scanner(System.in);

この行ではScannerオブジェクトを作成して、ユーザーからの入力を受け取る準備をします。

Scannerはキーボード入力を簡単に処理できる便利なクラスです。

HashMapの作成

HashMap<String, Integer> studentHashMap = new HashMap<>();

HashMapはキーと値をペアで保存するデータ構造です。

この場合キーとして生徒の名前(String型)、値として点数(Integer型)を保存します。

HashMapは順序が保証されていない点が特徴です。

ユーザーから3人の生徒情報を入力

for (int i = 0; i < 3; i++) {
    System.out.print("生徒の名前を入力してください: ");
    String name = scanner.nextLine();
    System.out.print(name + "の点数を入力してください: ");
    int score = scanner.nextInt();
    scanner.nextLine(); // 改行を消費する
    studentHashMap.put(name, score);
}

ここではforループを使って、ユーザーに3人の生徒の名前と点数を入力してもらいます。

そしてそれらのデータをHashMapに格納します。

TreeMapの作成

TreeMapHashMapと同様にキーと値をペアで保存しますが、大きな違いはキーが自然順序(この場合はアルファベット順)に自動的にソートされる点です。

ここではHashMapのデータを元にTreeMapを作成して、生徒の名前をアルファベット順に保存しています。

HashMapの内容を表示

printHashMap(studentHashMap);

このメソッドではHashMapに格納されている名前と点数を入力された順番に表示します。

HashMapは順序を保証しないため、出力される順序は予測できません。

TreeMapの内容を表示

printTreeMap(studentTreeMap);

このメソッドではTreeMapに格納されているデータをキー(名前)のアルファベット順に表示します。

TreeMapは常にキーの自然順序でデータを並べ替えるため、名前がアルファベット順で表示されることが保証されます。

まとめ

このプログラムではHashMapTreeMapの違いを学びながら、生徒の名前と点数を格納し、それを入力順とアルファベット順で表示しています。

TreeMapを使うとデータをキーに基づいてソートすることができ、順序が重要な場面で非常に役立ちます。

もっと分かりやすい学習サイトにするために

この記事を読んで「ここが分かりにくかった」「ここが難しかった」等の意見を募集しています。

世界一わかりやすいJava学習サイトにするため、ぜひ 問い合わせフォーム からご意見下さい。

<<前のページ

学習記事一覧

次のページ>>

記事URLをコピーしました