Java
 Computer >> コンピューター >  >> プログラミング >> Java

JavaでカスタムHashSetを実装する方法をサンプルコード付きで解説

HashSetとは

HashSetSetインターフェースを実装したコレクションクラスで、重複した値を許可しないという大きな特徴を持っています。また、HashSetは同期化されておらずスレッドセーフではないため、マルチスレッド環境で利用する際は注意が必要です。

HashSetにすでに存在する要素と同じものを追加しようとした場合、add()メソッドはfalseを返し、重複した要素はセットに登録されません。

構文

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable

カスタムHashSetの実装方法

実は、Java標準のHashSetは内部的にHashMapを使って実装されています。同じ仕組みを採用すれば、AbstractSetクラスを継承することで、独自のカスタムHashSetを簡単に作成できます。

以下の例では、HashMapを内部フィールドとして保持し、add()iterator()size()の各メソッドをオーバーライドしたカスタムHashSetを実装しています。

サンプルコード

import java.util.*;

public class CustomHashSetTest extends AbstractSet<Object> {

   private HashMap<Object, Object> map;

   // マップの値として使うダミーオブジェクト
   private static final Object PRESENT = new Object();

   public CustomHashSetTest() {
      map = new HashMap<>();
   }

   @Override
   public boolean add(Object e) {
      // キーが重複している場合、put()はnull以外を返すためfalseになる
      return map.put(e, PRESENT) == null;
   }

   @Override
   public Iterator<Object> iterator() {
      return map.keySet().iterator();
   }

   @Override
   public int size() {
      return map.size();
   }

   public static void main(String[] args) {
      CustomHashSetTest set = new CustomHashSetTest();
      set.add("England");
      set.add("Australia");
      set.add("India");
      set.add("India"); // 重複要素は追加されない

      for (Object element : set) {
         System.out.println(element);
      }
   }
}

実行結果

England
Australia
India

実装のポイント

  • 重複排除の仕組み: HashMapのキーは重複できません。同じ要素を再度追加するとput()が既存の値を返すため、戻り値がnullかどうかで新規追加か重複かを判定できます。
  • ダミーオブジェクトの活用: HashSetでは「値」ではなく「キー」だけが重要です。そのため、マップの値にはすべて同じダミーオブジェクト(PRESENT)を格納します。実際のjava.util.HashSetも同様の手法を採用しています。
  • 要素の順序について: 内部にHashMapを使っているため、要素の並び順は保証されません。挿入順を維持したい場合はLinkedHashMapを、ソートされた順序が必要な場合はTreeMapを内部に使うことで対応できます。
  1. 【Java入門】JScrollPaneでスクロール可能なJPanelを実装する方法

    JPanelとはJPanelはSwingで最もよく使われるコンテナの一つです。まずは基本的な特徴を確認しておきましょう。JPanelはJComponentのサブクラスであり、JComponentはContainerクラスのサブクラスです。したがって、JPanel自体もContainer(コンテナ)として扱えます。JPanelは、他のコンポーネントやパネルを配置するための「空の領域」として利用できます。テキストフィールド、ラベル、ボタン、チェックボックス、画像など、さまざまなコンポーネントを自由に追加できます。FlowLayout、GridLayout、BorderLayoutなどのレイアウトマ

  2. JavaのJToggleButton実装ガイド:ON/OFF切替ボタンの作り方を解説

    JToggleButtonとは JToggleButtonはAbstractButtonを拡張したクラスで、クリックするたびにONとOFFが切り替わるトグルボタンを実現するために使用されます。通常のボタンと異なり、押した状態を保持できるのが特徴です。 JToggleButtonの主な特徴 最初に押されたときは押し込まれた状態のままとなり、もう一度押してはじめて元の状態(押されていない状態)に戻ります。 ボタンが押されるたびにActionEventが発生します。 さらに、JToggleButtonはItemEventも発生させることができます。このイベントは、選択状態という概念を持つコンポー