この記事で学べる知識:HashSetとTreeSet
この記事の練習問題で使用する知識:
基礎構文、制御構造、メソッド(レッスン1~3)、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; // HashSetを使用するためのインポート文 public class HashSetExample { public static void main(String[] args) { // HashSetの作成 HashSet<String> set = new HashSet<>();//String型のsetというHashSetを作成 // addメソッドを使って要素の追加 set.add("Apple"); set.add("Banana"); set.add("Orange"); set.add("Apple"); // 重複要素(追加されません) // HashSetの内容を表示 System.out.println("HashSetの内容: " + set); // containsメソッドを使って要素の検索 if (set.contains("Banana")) { System.out.println("Bananaが含まれています"); } // removeメソッドを使って要素の削除 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; // TTreeSetを使用するためのインポート文 public class TreeSetExample { public static void main(String[] args) { // TreeSetの作成 TreeSet<String> set = new TreeSet<>(); //String型のsetというTreeSetを作成 // addメソッドを使って要素の追加(自動的にソートされます) 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()); // removeメソッドを使って要素の削除 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練習問題4-2:HashSetとTreeSetの違いを理解しよう
Javaのコレクションフレームワークを理解するために、HashSetとTreeSetを使って生徒の名前を管理するプログラムを作成しましょう。
このプログラムではユーザーから3人の生徒の名前を入力し、それらをHashSetとTreeSetに格納して表示します。
HashSetは名前を追加した順に表示し、TreeSetは名前をアルファベット順に表示します。
この問題の要件
以下の要件を満たすプログラムを作成してください。
- ユーザーから3人の生徒の名前を入力し、それらの名前をHashSetに格納すること。
- HashSetの内容を表示すること。
- HashSetの内容をTreeSetに格納し、名前をアルファベット順に表示すること。
printSet
というメソッドを作成し、セットの内容を表示すること。
ただし、以下のような実行結果となること。
----- ↓出力される結果の例↓ -----
生徒の名前を入力してください: 田中 生徒の名前を入力してください: 鈴木 生徒の名前を入力してください: 佐藤 HashSetを使って記載: 田中 鈴木 佐藤 TreeSetを使って名前のアルファベット順に記載: 佐藤 鈴木 田中
----- ↑出力される結果の例↑ -----
この問題を解くヒント
1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。
正解のコードは上から順に以下のような構成となっています。
1:HashSetクラスをインポート
2:Scannerクラスをインポート
3:TreeSetクラスをインポート
4:SetExampleクラスの定義
□ mainメソッドの定義
□ □ Scannerオブジェクトscannerの初期化
□ □ HashSetオブジェクトstudentHashSetの初期化
□ □ forループを3回繰り返すように設定
□ □ □ 「生徒の名前を入力してください: 」と出力
□ □ □ ユーザーの入力を文字列として読み取り、変数nameに代入
□ □ □ studentHashSetにnameを追加
□ □ TreeSetオブジェクトstudentTreeSetをstudentHashSetで初期化
□ □ 「HashSetを使って記載:」と出力
□ □ printSetメソッドでstudentHashSetの内容を出力
□ □ 「TreeSetを使って名前のアルファベット順に記載:」と出力
□ □ printSetメソッドでstudentTreeSetの内容を出力
□ printSetメソッドの定義
□ □ forループで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); /*【穴埋め問題1】 ここでHashSetを作成し、String型の要素を格納できるようにしてください。 */ // 3人の生徒の名前を入力してもらう for (int i = 0; i < 3; i++) { System.out.print("生徒の名前を入力してください: "); String name = scanner.nextLine(); /*【穴埋め問題2】 ここでHashSetにユーザーが入力した名前を追加してください。 */ } /*【穴埋め問題3】 ここでTreeSetを作成し、HashSetを使って初期化してください。 */ // HashSetの内容を表示 System.out.println("HashSetを使って記載:"); printSet(studentHashSet); // TreeSetの内容を表示 System.out.println("TreeSetを使って名前のアルファベット順に記載:"); printSet(studentTreeSet); } // Setの内容を表示するメソッド public static void printSet(java.util.Set<String> set) { // Setから名前を一つずつ取り出して表示 for (String name : set) { System.out.println(name); } } }
この問題の穴埋めコードは以上です。
このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。
解答例
この問題の一つの正解例とそのコードの解説を以下に示します。
正解コードの例
例えば以下のようなプログラムが考えられます。
********************
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); } // 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を活用しています。
問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。