HashSet与HashMap 怎么判断集合元素重复

HashSet的底层是用HashMap来维护的,所以两个问题可以理解为一个问题。

先看HashSet的部分源码

HashSet 类中的add()方法:

//维护数据的HashMap
private transient HashMap<E,Object> map;
//value的trick值。
private static final Object PRESENT = new Object();

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

从源码可以看到,就是把HashSet传入的对象当做HashMap的key进行处理。

put()方法:

 public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        //获取key的hash值
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        //遍历table中的元素
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            //关键代码
            // 如果hash相同并且 (两个key的对象相同 或者 两个key的equals()返回true)。
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                //此刻返回已经存储的值,所以不会对新的Entry进行存储
                return oldValue;
            }
        }
        //修改次数+1
        modCount++;
        //对新的Entry进行存储
        addEntry(hash, key, value, i);
        return null;
}

从源码中可以看出,如果有元素和传入对象的hash值相等,那么,继续进行equles()判断,如果仍然相等,那么就认为传入元素已经存在,不再添加,结束,否则仍然添加;

发布了206 篇原创文章 · 获赞 68 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/u013728021/article/details/102891249