HashSetとCopyOnWriteArraySet
10724 ワード
前言
この文章の目的は以下の通りです。
まずSetインタフェースを見てみましょう
1 public interface Set extends Collection {
2
3 int size();
4 boolean isEmpty();
5 boolean contains(Object o);
6 Object[] toArray();
7 T[] toArray(T[] a);
8 boolean add(E e);
9 boolean remove(Object o);
10 boolean containsAll(Collection> c);
11 boolean addAll(Collection extends E> c);
12 boolean retainAll(Collection> c);
13 boolean removeAll(Collection> c);
14 boolean equals(Object o);
15 int hashCode();
16 }
私たちは以上のインタフェースからSetがgetとsetの方法を持っていないことを発見しました.つまり、調べたり変えたりしていません.なぜですか.理由は次のとおりです.
1 HashSetはどのように要素が重複しないことを保証しますか?
HashSetがどのようにして中の要素が重複しないことを保証するかを明らかにするには、以下の2つの面から始めなければなりません.
私たちが上記の2つの問題を明らかにした後、HashSetがなぜ無秩序なのかを理解することができます.
1)HashSetの下位ストレージロジック
ソースコードを見てみましょう.
1 public class HashSet
2 extends AbstractSet
3 implements Set, Cloneable, java.io.Serializable{
4 static final long serialVersionUID = -5024744406713321676L;
5
6 private transient HashMap map;
7
8 // Dummy value to associate with an Object in the backing Map
9 private static final Object PRESENT = new Object();
10
11 /**
12 * Constructs a new, empty set; the backing HashMap instance has
13 * default initial capacity (16) and load factor (0.75).
14 */
15 public HashSet() {
16 map = new HashMap<>();
17 }
18 ...
19 }
HashSetの下位ストレージ構造はHashMapであり,HashSetの要素はこのMapのKeyとして格納され,HashMapのKeyの格納は無秩序で繰り返し不可能であることを示し,HashSetにおいてどのように要素が繰り返されないことを保証するかを説明した.
2)挿入ロジック
public boolean add(E e) {return map.put(e, PRESENT)==null;}
直接mapにputする
3)まとめ
以上より、HashSetの下位ストレージ構造がHashMapであり、mapのキーとしてHashSetに挿入された要素が格納されていることがわかり、HashSetの特徴を保証します.
2 HashSet追加削除(変更?)げんり
前のセクションでは、HashSetの最下位ストレージ構造がHashMapであることを理解しました.では、その削除はmapのputとremoveです.
1)増加
public boolean add(E e) {return map.put(e, PRESENT)==null;}
直接mapにputする
2)削除
public boolean remove(Object o) {return map.remove(o)==PRESENT;}
mapから直接削除すれば簡単です
3 CopyOnWriteArraySetはなぜコンカレントをサポートできるのですか?
CopyOnWriteArraySetがなぜコンカレントをサポートできるのかを明らかにする前に、次のいくつかの問題を考えてみましょう.
上記の2つの問題を明らかにすると、CopyOnWriteArraySetがなぜ同時サポートできるのかを知っていると思います.にさせておく
まず、CopyOnWriteArraySetのソースコードの一部を見てみましょう.
1 public class CopyOnWriteArraySet extends AbstractSet
2 implements java.io.Serializable {
3 private static final long serialVersionUID = 5457747651344034263L;
4
5 private final CopyOnWriteArrayList al;
6
7 /**
8 * Creates an empty set.
9 */
10 public CopyOnWriteArraySet() {
11 al = new CopyOnWriteArrayList();
12 }
13 ...
14 }
ソースコードからCopyOnWriteArraySetの下位ストレージ構造がCopyOnWriteArrayListであることが不思議にわかり、名前の由来を知ることができ、CopyOnWriteArrayListと同じ原理をサポートしていることがわかります.
附:CopyOnWriteArrayList原理解析
4 CopyOnWriteArraySetの追加削除(変更?)げんり
1)増加
public boolean add(E e) {
return al.addIfAbsent(e);
}
メソッド名を見ると、CopyOnWriteArrayListに要素が存在しない場合に追加に成功します.
2)削除
public boolean remove(Object o) {
return al.remove(o);
}
CopyOnWriteArrayListから直接削除
5まとめ
答え:HashSetの下位ストレージ構造はHashMapであり、HashSetの要素はMapのKeyとしてMapに格納されているため、HashMapのKeyは重複せず無秩序であるため、HashSetの要素は重複しない無秩序である
HashSetの削除原理は簡単です.mapのputとremoveです.どうして変更しなかったのですか.それはHashSetの要素が無秩序なため、インデックスに基づいてクエリーや変更ができないからです.
CopyOnWriteArraySet CopyOnWriteArraySetと呼ばれるのは、最下位のストレージ構造がCopyOnWriteArrayListであり、同時セキュリティが保証されているからです.
CopyOnWriteArraySetはAbstractSetを継承しており、HashSetと同様に添削のみであり、改ざんはされていない.添削原理はCopyOnWriteArrayListを呼び出す添削方法であるが、増設する場合はリストにその要素が格納されているか否かを判断する必要がある