【JAVA】レッスン4-02:HashSetとTreeSetを理解しよう

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:HashSetとTreeSet

この記事の練習問題で使用する知識:
基礎構文、制御構造、メソッド(レッスン1~3)ArrayListHashSetTreeSetHashMapTreeMap

<<前のページ 問題集Top 次のページ>>

JAVAの文法「コレクション(HashSet, TreeSet)」とは

ここではコレクション(HashSet, TreeSet)の意味や使い方を学習します。必要ない方はここをクリックして練習問題へ飛びましょう。




Javaのコレクションフレームワークは、データを効率的に管理し操作するために非常に役立ちます。

その中でも「Set」インターフェースは、重複する要素を許さないコレクションです。

今回はHashSetTreeSetという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の使いどころ

  • データを常にソートされた状態で保持したい場合。
  • 特定の範囲での検索やソートが必要な場合。

HashSetTreeSetの違いまとめ

特徴 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【コードの構成を見る】

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

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内の各名前を出力

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

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

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に追加しています。

HashSetaddメソッドは要素をコレクションに追加するために使いますが、すでに同じ名前が入っている場合は追加されません。

TreeSetを作成して名前をソートする

TreeSet<String> studentTreeSet = new TreeSet<>(studentHashSet);

次にHashSetから名前を取り出して、それをアルファベット順にソートするためにTreeSetを作成します。

TreeSetは要素を常に昇順に保ちながら管理するデータ構造です。

この行ではHashSetTreeSetのコンストラクタに渡して、名前を自動的にソートしています。

HashSetとTreeSetの内容を表示する

printSet(studentHashSet);
printSet(studentTreeSet);

最後にprintSetメソッドを使って、HashSetTreeSetの内容をそれぞれ表示しています。

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を活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    JAVAテキスト&問題集へ戻る
    トップページへ戻る