JavaのSet

Java本格入門でSetについて読んだので、それのメモ。

Set

値の集合を扱うことができるインターフェース

List同様、要素を追加するaddメソッドがあるが、要素を取得するgetはない。

値を扱うインターフェースであるため、特定の要素の取得もできない

重複する要素を持たない

Setの内部にはMapが存在し、Setに追加された要素は内部のMapのキーとして保持される(Mapのキーは重複NG)

Setの基本的な使い方

・初期化

Set<Integer> Set = new HashSet<>();


・コレクションをSetに変換した時、

public class Main {
    
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();

        List<Integer> list = Arrays.asList(1,2,3,3,4,1,5);
        System.out.println(list);
        //-> [1, 2, 3, 3, 4, 1, 5]

        //ListをSetに変換
        Set<Integer> set2 = new HashSet<>(list);
        System.out.println(set2);
        //-> [1, 2, 3, 4, 5]
    }
}

Setに変換した際は重複は除外される。

配列から直接Setに変換はできないので、

配列→List→Set

という流れで変換しないといけない。


・基本的な処理

public class Main {
    
    public static void main(String[] args) {
        Set<Integer> numbers = new HashSet<>();

        //値の追加
        numbers.add(1);
        numbers.add(24);
        numbers.add(3);
        numbers.add(12);
        numbers.add(6);
        System.out.println(numbers);
        //-> [1, 3, 6, 24, 12]
        
        //値の上書き
        numbers.add(3);
        System.out.println(numbers);
        //-> [1, 3, 6, 24, 12]
        // 3が重複するのではなく、上書かれる

        numbers.remove(12);
        System.out.println(numbers);
        //-> [1, 3, 6, 24]

        int size = numbers.size();
        System.out.println(size);
        //-> 4

        boolean existValue = numbers.contains(24);
        System.out.println(existValue);
        //-> true
    }
}
Setの実装クラス

・HashSet(java.util.HashSet)
値からハッシュ値を計算して、内部のハッシュ テーブルという表に値を格納して要素を管理する。
追加した順に要素が保持されない。

スレッドセーフではないので、
synchronizedを使用して排他制御を行う
ConcurrentHashMapからSetを作成してスレッドセーフにする
などの対応が必要。


・LinkedHashSet(java.util.LinkedHashSet)
HashSetのサブクラス。
LinkedListのように、要素自信が前後情報を持つ。
追加した順番に要素が保持される。
要素の列挙はHashSetよりもこっちのほうが高速。


・TreeSet
キーの値を元に、2分探索木のアルゴリズムで要素をソートするクラス。
要素の追加時にソートされて保持される。

「〇〇以上〇〇以下のキーを持つ要素の取得」
「〇〇より大きな、もっとも近いキーを持つ要素を取得」
などのように、大小を意識した値の取得ができる。

まとめ

重複のない要素の集合を扱えることがわかったが、具体的な使い所に関してはいまいちわからず、、、

要素の集合から任意の値を使って何かをするというよりは、
要素の集合に対して、存在するかどうかだったり、サイズの確認などを使ってロジックに利用するのだろうか。。。

普段の仕事でSetの使われ方を意識して見て行こうと思う。