------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
HashSet集合储存的元素的唯一性是怎么保证的呢?
1.查看add方法源码:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
//由此可见,使用的是map的put方法
}
2.查看map
private transient HashMap<E,Object> map;
可以看到map是HashSet的一个成员变量,但是这个成员变量是HashMap类型
3.查看HashMap,是一个类
所以add方法最终使用的是HashMap的put方法
4.查看put方法
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))) { //首先判断哈希值是否相等,然后判断地址值,最后判断equals方法的结果
V oldValue = e.value; //如果判断结果是false,则跳出循环,直接添加该元素。
e.value = value;
e.recordAccess(this);
return oldValue; //如果走到这一步说明不会添加元素
}
} //for循环结束
//如果没进for循环或for循环的判断结果为假,则直接添加元素
modCount++;
addEntry(hash, key, value, i);
return null;
}
5.由put方法的分析可以知道
是否可以添加则取决于hashCode()方法和equals()方法,
判断过程如下:
首先,判断哈希值,如果哈希值相同则不添加
如果哈希值不相同,看元素的equals方法比较的内容是否相同,如果也相同则不添加。
6.所以在hashSet中储存元素时得到以下结论
A:如果元素是String类型
由于String重写了hashCode()和equals()方法,所以hashSet只存储内容不同的字符串。
B:如果元素是普通自定义对象
要看该类是否重新了hashCode()和equals()方法,自动重写比较的对象的成员变量的值