JAVAの初心者向け問題3-2:HashSetとTreeSetの違いを理解しよう
この問題を解くために必要な知識:
【レベル1~2の知識】
コメントの書き方、変数と定数、基本データ型とプリミティブ型、四則演算と論理演算、入力と出力(Scannerクラス)、配列、分岐処理(if、if~else、switch)、繰り返し処理(for、while、do~while)、メソッドの定義と呼び出し、メソッドの戻り値、メソッドのオーバーロード、例外処理(try-catch文、throws、throw)、クラスの定義と使用、インスタンス、コンストラクタ
【レベル3の知識】
コレクションの基礎、コレクション(List, ArrayList)、コレクション(HashSet, TreeSet)、コレクション(HashMap, TreeMap)
<<前の問題 | 問題集Top |
次の問題>> |
JAVAの文法「コレクション(HashSet, TreeSet)」とは
ここではコレクション(HashSet, TreeSet)の意味や使い方を復習します。必要ない方はここをクリックして練習問題へ飛びましょう。
Javaのコレクションフレームワークは、データを効率的に管理し操作するために非常に役立ちます。
その中でも「Set」インターフェースは、重複する要素を許さないコレクションです。
今回は、HashSet
とTreeSet
という2つの代表的な実装クラスについて解説します。
HashSet
とは?
HashSet
は、Setインターフェースの実装クラスの一つで、順序を保持しないコレクションです。
要素が重複しないように管理され、格納された順序が保証されません。これは、内部的にハッシュテーブルを使用して要素を管理するためです。
特徴:
- 要素の重複を許さない。
- 順序は保証されない。
null
要素も一つだけ追加可能。- 検索や削除が高速。
例:HashSet
の基本的な使い方
以下のコードは、HashSet
を使って基本的な操作を行う例です。
import java.util.HashSet; public class HashSetExample { public static void main(String[] args) { // HashSetの作成 HashSet<String> set = new HashSet<>(); // 要素の追加 set.add("Apple"); set.add("Banana"); set.add("Orange"); set.add("Apple"); // 重複要素(追加されません) // HashSetの内容を表示 System.out.println("HashSetの内容: " + set); // 要素の検索 if (set.contains("Banana")) { System.out.println("Bananaが含まれています"); } // 要素の削除 set.remove("Orange"); System.out.println("削除後のHashSet: " + set); } }
実行結果:
HashSetの内容: [Banana, Apple, Orange] Bananaが含まれています 削除後のHashSet: [Banana, Apple]
HashSet
の使いどころ
- データの順序が重要ではない場合。
- 高速な検索や削除が求められる場合。
TreeSet
とは?
TreeSet
は、Setインターフェースを実装したクラスで、要素を昇順に自動的に並び替えて保持する特性を持っています。
内部的には赤黒木というデータ構造を使用し、要素の追加や削除が行われるたびに要素をソートします。
特徴:
- 自動的に要素を昇順にソート。
- 要素の重複を許さない。
null
要素を保持できない(HashSet
とは異なる点)。
例:TreeSet
の基本的な使い方
以下のコードは、TreeSet
を使った基本的な操作の例です。
import java.util.TreeSet; public class TreeSetExample { public static void main(String[] args) { // TreeSetの作成 TreeSet<String> set = new TreeSet<>(); // 要素の追加(自動的にソートされます) set.add("Banana"); set.add("Apple"); set.add("Orange"); set.add("Grape"); // TreeSetの内容を表示(昇順に並び替えられる) System.out.println("TreeSetの内容: " + set); // 最初の要素を取得 System.out.println("最初の要素: " + set.first()); // 最後の要素を取得 System.out.println("最後の要素: " + set.last()); // 要素の削除 set.remove("Banana"); System.out.println("削除後のTreeSet: " + set); } }
実行結果:
TreeSetの内容: [Apple, Banana, Grape, Orange] 最初の要素: Apple 最後の要素: Orange 削除後のTreeSet: [Apple, Grape, Orange]
TreeSet
の使いどころ
- データを常にソートされた状態で保持したい場合。
- 特定の範囲での検索やソートが必要な場合。
HashSet
とTreeSet
の違いまとめ
特徴 | HashSet | TreeSet |
順序 | 順序を保持しない | 昇順にソートされる |
処理速度 | 検索・追加が高速 | ソートがあるため少し遅い |
null要素 | 許可される | 許可されない |
データ構造 | ハッシュテーブル | 赤黒木 |
どちらを使うべきか?
- 順序が不要で、パフォーマンス重視の場合:
HashSet
- 順序を保ちながらデータを管理したい場合:
TreeSet
どちらも一長一短があるため、目的に応じて使い分けることが大切です。まずはこの2つのコレクションを実際にコードで試し、理解を深めてください。
JAVA練習問題3-2:HashSetとTreeSetの違いを理解しよう
Javaのコレクションフレームワークを理解するために、HashSetとTreeSetを使って生徒の名前を管理するプログラムを作成しましょう。
このプログラムでは、ユーザーから3人の生徒の名前を入力し、それらをHashSetとTreeSetに格納して表示します。
HashSetは名前を追加した順に表示し、TreeSetは名前をアルファベット順に表示します。
この問題の要件
以下の要件を満たすプログラムを作成してください。
- ユーザーから3人の生徒の名前を入力し、それらの名前をHashSetに格納すること。
- HashSetの内容を表示すること。
- HashSetの内容をTreeSetに格納し、名前をアルファベット順に表示すること。
printSet
というメソッドを作成し、セットの内容を表示すること。
ただし、以下のような実行結果となること。
----- ↓出力される結果の例↓ -----
生徒の名前を入力してください: 田中 生徒の名前を入力してください: 鈴木 生徒の名前を入力してください: 佐藤 HashSetを使って記載: 田中 鈴木 佐藤 TreeSetを使って名前のアルファベット順に記載: 佐藤 鈴木 田中
----- ↑出力される結果の例↑ -----
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
1.import文
1-1. HashSetクラスのインポート
1-2. Scannerクラスのインポート
1-3. TreeSetクラスのインポート
2.SetExampleクラスの定義
2-1. mainメソッド
2-1-1. Scannerオブジェクトの作成
2-1-2. 生徒の名前を格納するためのHashSetの作成
2-1-3. forループを使用して3人の生徒の名前を入力
2-1-3-1. 生徒の名前を入力するためのメッセージを表示
2-1-3-2. 入力された名前をHashSetに追加
2-1-4. TreeSetオブジェクトの作成
2-1-4-1. HashSetの内容をTreeSetに追加
2-1-5. HashSetの内容を表示
2-1-5-1. printSetメソッドの呼び出し
2-1-6. TreeSetの内容を表示
2-1-6-1. printSetメソッドの呼び出し
2-1-7. Scannerオブジェクトを閉じる
3.printSetメソッドの定義
3-1. Setの内容を一つずつ取り出して表示
以下のコードをコピーし、コメントに従ってコードを完成させて下さい。
import java.util.HashSet; import java.util.Scanner; import java.util.TreeSet; public class SetExample { // メインメソッド public static void main(String[] args) { // スキャナを作成してユーザー入力を受け取る Scanner scanner = new Scanner(System.in); // 生徒の名前を格納するHashSetを作成 HashSet<String> studentHashSet = new HashSet<>(); // 3人の生徒の名前を入力してもらう for (int i = 0; i < 3; i++) { System.out.print("生徒の名前を入力してください: "); // ***ここにユーザーから名前を入力してHashSetに追加するコードを書いてください。*** } // 生徒の名前を格納するTreeSetを作成 // ***ここにHashSetの内容をTreeSetに格納するコードを書いてください。*** // HashSetの内容を表示 System.out.println("HashSetを使って記載:"); // ***ここでprintSetメソッドを呼び出してHashSetの内容を表示するコードを書いてください。*** // TreeSetの内容を表示 System.out.println("TreeSetを使って名前のアルファベット順に記載:"); // ***ここでprintSetメソッドを呼び出してTreeSetの内容を表示するコードを書いてください。*** // スキャナを閉じる scanner.close(); } // Setの内容を表示するメソッド public static void printSet(java.util.Set<String> set) { // Setから名前を一つずつ取り出して表示 // ***ここにSetから名前を取り出して表示するコードを書いてください。*** } }
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
解答例
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
********************
import java.util.HashSet; import java.util.Scanner; import java.util.TreeSet; public class SetExample { // メインメソッド public static void main(String[] args) { // スキャナを作成してユーザー入力を受け取る Scanner scanner = new Scanner(System.in); // 生徒の名前を格納するHashSetを作成 HashSet<String> studentHashSet = new HashSet<>(); // 3人の生徒の名前を入力してもらう for (int i = 0; i < 3; i++) { System.out.print("生徒の名前を入力してください: "); String name = scanner.nextLine(); studentHashSet.add(name); } // 生徒の名前を格納するTreeSetを作成 TreeSet<String> studentTreeSet = new TreeSet<>(studentHashSet); // HashSetの内容を表示 System.out.println("HashSetを使って記載:"); printSet(studentHashSet); // TreeSetの内容を表示 System.out.println("TreeSetを使って名前のアルファベット順に記載:"); printSet(studentTreeSet); // スキャナを閉じる scanner.close(); } // Setの内容を表示するメソッド public static void printSet(java.util.Set<String> set) { // Setから名前を一つずつ取り出して表示 for (String name : set) { System.out.println(name); } } }
********************
コードの解説
今回のコードは、生徒の名前を入力して、それをHashSet
で格納し、さらにその名前をアルファベット順に並べるためにTreeSet
を使用しています。
スキャナを使ってユーザーから入力を受け取る
Scanner scanner = new Scanner(System.in);
Scanner
クラスを使って、ユーザーからコンソールで入力を受け取る準備をしています。System.in
はコンソール(キーボード入力)からの入力を表します。
HashSetを作成する
HashSet<String> studentHashSet = new HashSet<>();
ここでは、生徒の名前を格納するためのHashSet
を作成しています。HashSet
は、要素を重複させずに管理するデータ構造です。
順序は保証されませんが、要素の追加や削除が高速で行われます。
生徒の名前を入力してHashSetに追加する
for (int i = 0; i < 3; i++) { System.out.print("生徒の名前を入力してください: "); String name = scanner.nextLine(); studentHashSet.add(name); }
for
ループを使って、3人分の生徒の名前をユーザーから入力してもらい、それをHashSet
に追加しています。
HashSet
のadd
メソッドは、要素をコレクションに追加するために使いますが、すでに同じ名前が入っている場合は追加されません。
TreeSetを作成して名前をソートする
TreeSet<String> studentTreeSet = new TreeSet<>(studentHashSet);
次に、HashSet
から名前を取り出して、それをアルファベット順にソートするためにTreeSet
を作成します。
TreeSet
は、要素を常に昇順に保ちながら管理するデータ構造です。
この行では、HashSet
をTreeSet
のコンストラクタに渡して、名前を自動的にソートしています。
HashSetとTreeSetの内容を表示する
printSet(studentHashSet); printSet(studentTreeSet);
最後に、printSet
メソッドを使って、HashSet
とTreeSet
の内容をそれぞれ表示しています。
HashSet
は追加された順序が保証されないため、表示順は入力された順とは異なる可能性がありますが、TreeSet
はアルファベット順で表示されます。
Setの内容を表示するためのメソッド
public static void printSet(java.util.Set<String> set) { for (String name : set) { System.out.println(name); } }
Set
に格納されている名前を1つずつ取り出し、for-each
ループでコンソールに表示しています。
このメソッドは、HashSet
でもTreeSet
でも同じように使えます。
<<前の問題 |
問題集Top |
次の問題>> |
この問題への質問・コメント
この問題を作成するにあたりAIを活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。