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の使われ方を意識して見て行こうと思う。