/**
* Adds the specified element to this set if it is not already present.
* More formally, adds the specified element <tt>e</tt> to this set if
* this set contains no element <tt>e2</tt> such that
* <tt>(e==null ? e2==null : e.equals(e2))</tt>.
* If this set already contains the element, the call leaves the set
* unchanged and returns <tt>false</tt>.
*
* @param e element to be added to this set
* @return <tt>true</tt> if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
向HashSet内部维护的map添加新元素 //HashMap代码
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
*/
public V put(K key, V value) {
if (table == EMPTY_TABLE) {
inflateTable(threshold);
}
if (key == null)
return putForNullKey(value);
int hash = hash(key);
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}
/**
* Returns <tt>true</tt> if this set contains the specified element.
* More formally, returns <tt>true</tt> if and only if this set
* contains an element <tt>e</tt> such that
* <tt>(o==null ? e==null : o.equals(e))</tt>.
*
* @param o element whose presence in this set is to be tested
* @return <tt>true</tt> if this set contains the specified element
*/
public boolean contains(Object o) {
return map.containsKey(o);
}
//HashMap代码
/**
* Returns <tt>true</tt> if this map contains a mapping for the
* specified key.
*
* @param key The key whose presence in this map is to be tested
* @return <tt>true</tt> if this map contains a mapping for the specified
* key.
*/
public boolean containsKey(Object key) {
return getEntry(key) != null;
}
/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
final Entry<K,V> getEntry(Object key) {
if (size == 0) {
return null;
}
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
我查了下源碼,我覺得
HashSet
的Hash
這裡有文章。HashSet
的Hash
这里有文章。1.首先看添加元素的过程
//HashSet代码
向
HashSet
内部维护的map
添加新元素//HashMap代码
可以看出会对
Element
做哈希,所以如果添加Foo(1)
的话,保存到HashSet
过程中也少不了这个环节的。再来看比较的情况
//HashSet代码
//HashMap代码
结论
插入
HashSet
//HashSet程式碼
HashSet
內部維護的map
新增元素//HashMap程式碼🎜 rrreee 🎜可以看出會對
Element
做哈希,所以如果加入Foo(1)
的話,儲存到HashSet
過程中也少不了這個環節的。 🎜//HashSet程式碼🎜🎜🎜🎜🎜 rrreee 🎜//HashMap程式碼🎜 rrreee rrreee
插入
HashSet
容器時對元素做哈希,判斷容器是否含有某個元素時也要對元素做哈希,他們比較的是元素的雜湊值。 🎜🎜🎜🎜🎜equals的方法,但是值得注意的是二樓說的是String下的equals方法,因為String的equals方法是重寫過的,如果題主希望透過contains方法對於一般Object的比較的話,還是得和String一樣重寫equals方法,確定何種規則
這個是
AbstractCollection
的实现,AbstractList
,AbstractSet
都是以此為父類實現的.