JAVAの初心者向け問題3-4:HashMapとTreeMapの違いを理解しよう
この問題を解くために必要な知識:
【レベル1~2の知識】
コメントの書き方、変数と定数、基本データ型とプリミティブ型、四則演算と論理演算、入力と出力(Scannerクラス)、配列、分岐処理(if、if~else、switch)、繰り返し処理(for、while、do~while)、メソッドの定義と呼び出し、メソッドの戻り値、メソッドのオーバーロード、例外処理(try-catch文、throws、throw)、クラスの定義と使用、インスタンス、コンストラクタ
【レベル3の知識】
コレクションの基礎、コレクション(List, ArrayList)、コレクション(HashSet, TreeSet)、コレクション(HashMap, TreeMap)
<<前の問題 | 問題集Top |
次の問題>> |
JAVAの文法「TreeMap」とは
ここではTreeMapの意味や使い方を復習します。必要ない方はここをクリックして練習問題へ飛びましょう。
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; public class TreeMapExample { public static void main(String[] args) { // TreeMapのインスタンスを作成 TreeMap<Integer, String> treeMap = new TreeMap<>(); // 要素を追加 treeMap.put(3, "三"); treeMap.put(1, "一"); treeMap.put(2, "二"); // 要素の表示 System.out.println("TreeMapの内容: " + treeMap); // 特定のキーの値を取得 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の違い
TreeMapとよく比較されるのがHashMapです。どちらもキーと値のペアを保持するマップですが、それぞれ特徴が異なります。
ここでは、両者の違いを簡単にまとめます。
特徴 | TreeMap | HashMap |
ソート順 | キーが自然順序またはComparatorでソートされる | 挿入順序は保証されない |
内部構造 | 赤黒木を使用 | ハッシュテーブルを使用 |
パフォーマンス | データの挿入・削除にO(log n)の時間がかかる | O(1)に近い時間で操作が可能 |
nullの扱い | nullキーは許可されない | nullキーとnull値の両方が許可される |
主な用途 | データをソートされた状態で保持したいとき | 高速なデータ挿入と取得が必要なとき |
TreeMapとHashMapのどちらを使うべきか?
- データを順序通りに保持したい場合:キーのソートが必要な場面、例えば数値やアルファベット順で要素を処理したいときには、TreeMapが適しています。
- 高速なデータ操作が必要な場合:順序を気にせず、挿入や検索をできるだけ早く行いたいときは、HashMapを使用する方が効果的です。
例えば、アルファベット順にユーザーの名前を管理したい場合はTreeMapを使うと便利ですが、単純にユーザーIDと名前を対応させたいだけなら、HashMapの方が効率的でしょう。
JAVA練習問題3-4:HashMapとTreeMapの違いを理解しよう
あなたは学校の教師で、生徒のテストの点数を管理するプログラムを作成したいと考えています。
生徒の名前とその点数を入力し、それを使って以下の機能を実現するプログラムを作成してください。
この問題の要件
以下の要件を満たすプログラムを作成してください。
Scanner
クラスを使ってユーザーから生徒の名前と点数を3人分入力すること。HashMap
を使用して、入力された生徒の名前と点数を格納すること。HashMap
の内容を入力順に表示すること。HashMap
の内容をTreeMap
にコピーし、名前のアルファベット順に並び替えて表示すること。HashMap
の内容を表示するメソッドprintHashMap
を作成すること。TreeMap
の内容を表示するメソッドprintTreeMap
を作成すること。
ただし、以下のような実行結果となること。
----- ↓出力される結果の例↓ -----
生徒の名前を入力してください: 田中 田中の点数を入力してください: 85 生徒の名前を入力してください: 鈴木 鈴木の点数を入力してください: 92 生徒の名前を入力してください: 佐藤 佐藤の点数を入力してください: 78 HashMapを使って入力順に記載: 田中の点数は85点です。 鈴木の点数は92点です。 佐藤の点数は78点です。 TreeMapを使って名前のアルファベット順に記載: 佐藤の点数は78点です。 鈴木の点数は92点です。 田中の点数は85点です。
----- ↑出力される結果の例↑ -----
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
1.import文
1-1. HashMapクラスのインポート
1-2. Scannerクラスのインポート
1-3. TreeMapクラスのインポート
2.MapExampleクラスの定義
2-1. mainメソッド
2-1-1. Scannerオブジェクトの作成
2-1-2. 生徒の名前と点数を格納するためのHashMapオブジェクトの作成
2-1-3. 3人の生徒の情報を入力してもらうためのforループ
2-1-3-1. 生徒の名前を入力
2-1-3-2. 生徒の点数を入力
2-1-3-3. 入力された名前と点数をHashMapに格納
2-1-4. HashMapの内容をTreeMapにコピーするためのTreeMapオブジェクトの作成
2-1-5. HashMapの内容を表示
2-1-6. TreeMapの内容を表示
2-1-7. Scannerオブジェクトを閉じる
3.printHashMapメソッドの定義
3-1. 引数としてHashMapオブジェクトを受け取る
3-2. HashMapのキーと値を取り出して表示
4.printTreeMapメソッドの定義
4-1. 引数としてTreeMapオブジェクトを受け取る
4-2. TreeMapのキーと値を取り出して表示
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
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に名前と点数を追加するコードを書いてください。*** } // 生徒の名前と点数を格納するTreeMapを作成 // ***このコメントを消して、studentHashMapを基にしてstudentTreeMapを作成するコードを書いてください。*** // HashMapの内容を表示 System.out.println("HashMapを使って入力順に記載:"); // ***このコメントを消して、printHashMapメソッドを呼び出すコードを書いてください。*** // TreeMapの内容を表示 System.out.println("TreeMapを使って名前のアルファベット順に記載:"); // ***このコメントを消して、printTreeMapメソッドを呼び出すコードを書いてください。*** // スキャナを閉じる scanner.close(); } // HashMapの内容を表示するメソッド public static void printHashMap(HashMap<String, Integer> map) { // HashMapから名前と点数を一つずつ取り出して表示 // ***このコメントを消して、HashMapのキーと値を取り出して表示するコードを書いてください。*** } // TreeMapの内容を表示するメソッド public static void printTreeMap(TreeMap<String, Integer> map) { // TreeMapから名前と点数を一つずつ取り出して表示 // ***このコメントを消して、TreeMapのキーと値を取り出して表示するコードを書いてください。*** } }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
解答例
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
********************
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); // スキャナを閉じる scanner.close(); } // 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 + "点です。"); } } }
********************
コードの解説
このコードは、HashMap
とTreeMap
という2つの異なるマップ構造を使って、生徒の名前と点数を保存し、入力順とアルファベット順にそれぞれ表示するプログラムです。
次のステップで詳細に説明していきます。
スキャナの作成
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
の作成
TreeMap
もHashMap
と同様にキーと値をペアで保存しますが、大きな違いは、キーが自然順序(この場合はアルファベット順)に自動的にソートされる点です。
ここでは、HashMap
のデータを元にTreeMap
を作成して、生徒の名前をアルファベット順に保存しています。
HashMap
の内容を表示
printHashMap(studentHashMap);
このメソッドでは、HashMap
に格納されている名前と点数を入力された順番に表示します。
HashMap
は順序を保証しないため、出力される順序は予測できません。
TreeMap
の内容を表示
printTreeMap(studentTreeMap);
このメソッドでは、TreeMap
に格納されているデータをキー(名前)のアルファベット順に表示します。
TreeMap
は常にキーの自然順序でデータを並べ替えるため、名前がアルファベット順で表示されることが保証されます。
まとめ
このプログラムでは、HashMap
とTreeMap
の違いを学びながら、生徒の名前と点数を格納し、それを入力順とアルファベット順で表示しています。
TreeMap
を使うと、データをキーに基づいてソートすることができ、順序が重要な場面で非常に役立ちます。
<<前の問題 |
問題集Top |
次の問題>> |
この問題への質問・コメント
この問題を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。