私はいつも、JavaでSetをどのように実装するのか疑問に思っていました。 LinkedListとキーと値を保持するオブジェクト(セル)を使用してHashMapを実装するのと同じように実装できますか?独自性の部分をどのように扱いますか?
基本的に、セットはキーのみを保持する単なるマップです。したがって、マッピングアルゴリズムについて自分自身に通知する必要があります。注:たとえば、HashSetは、実際にはHashMapの単なるアダプターです。 HashSetのaddメソッドは、単にHashMap.put(value、SomeDummyValue)を使用します。
以下は、上記の回答を説明するためのコードスニペットです。
public HashSet() { map = new HashMap<>(); }
private transient HashMap<E,Object> map;
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
// Since PRESENT is a constant, for all keys we have same value in backup HashMap called map.
public Iterator<E> iterator() {
return map.keySet().iterator();
}
class HashSetBasicImpl<K> {
static class Entry<K> {
private K key;
private Entry<K> next;
Entry(K key) {
key = key;
next = null;
}
}
private Entry<K>[] entries;
public HashSetBasicImpl() {
// fixed size
map =new Entry[100];
}
public boolean contains(K key) {
int idx = key.hashCode();
Entry<K> start = entries[idx];
while(start != null) {
if(start.key == key) {
return true;
}
start = start.next;
}
return false;
}
public boolean add(K key) {
Entry<K> entry = new Entry(key);
int idx = key.hashCode();
// check if entry exists
if(contains(key)) {
return false;
}
// add as first entry
start = entries[idx];
if(start == null) {
entries[idx]= new Entry(key);
return true;
}
// add as nth entry
Entry prev = null;
while(start != null) {
prev = start;
start = start.next;
}
prev.next = new Entry(key);
return true;
}
}