HashSet集合的add()方法的源码

简介: interface Collection { ... } interface Set extends Collection { .
interface Collection {
    ...
}
interface Set extends Collection {
    ...
}
class HashSet implements  {
    private static final Object PRESENT = new Object();
    private transient HashMap<E,Object> ;
    
    public HashSet() {
        map = new HashMap<>();
    }
    
    public boolean add(E e) { //e=hello,world
        return .put(e, PRESENT)==null;
    }
}
class  implements Map {
    public V put(K key, V value) { //key=e=hello,world
    
        //看哈希表是否为空,如果空,就开辟空间
        if (table == EMPTY_TABLE) {
            inflateTable(threshold);
        }
        
        //判断对象是否为null
        if (key == null)
            return putForNullKey(value);
        
        int hash = (key); //和对象的hashCode()方法相关
        
        //在哈希表中查找hash值
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            //这次的e其实是第一次的world
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
                //走这里其实是没有添加元素
            }
        }

        modCount++;
        addEntry(hash, key, value, i); //把元素添加
        return null;
    }
    
    transient int hashSeed = 0;
    
    final int (Object k) { //k=key=e=hello,
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }

        h ^= k.(); //这里调用的是对象的hashCode()方法

        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
}
//对应源码 addEntry(hash, key, value, i); // 把元素添加
void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        if (size++ >= threshold)
            resize(2 * table.length);
    }
  1. hs.add("hello"
);//由于table里面没有,直接进addEntry
hs.add(
"world" );//同上
hs.add(
"java" );//同上
hs.add(
"world");//table里已经存在,(hash和equals相等),则在put()时,用新值替代老值。ps:这里的老值和新值都是world。

总结:

首先比较哈希值
    如果相同,继续走,比较地址值或者走equals()
    如果不同,就直接添加到集合中
按照方法的步骤来说:
    先看hashCode()值是否相同
        相同:继续走equals()方法
            返回true:说明元素重复,就不添加
            返回false:说明元素不重复,就添加到集合
        不同:就直接把元素添加到集合
如果类没有重写这两个方法,默认使用的Object()。一般磊说不会相同。
而String类重写了hashCode()和equals()方法,所以,它就把内容相同的字符串去掉,只留下一个。

开始做,坚持做,重复做
相关文章
|
22天前
|
存储 安全 Java
Java集合详解(List、Map、Set)
Java集合详解(List、Map、Set)
32 4
|
9月前
|
存储 开发者 索引
List 和 Set 集合的区别
List 和 Set 集合的区别
73 0
|
8月前
|
Kotlin
Kotlin 中List集合,Set集合,Map集合,数组的详解
Kotlin 中List集合,Set集合,Map集合,数组的详解
59 0
|
10月前
|
人工智能
List集合中 中contains方法的使用详解
List集合中 中contains方法的使用详解
|
10月前
Map、Set、List集合区别(看完秒懂)
Map、Set、List集合区别(看完秒懂)
73 0
|
10月前
|
索引
LinkedList源码分析之 add 方法(一)
LinkedList源码分析之 add 方法(一)
49 2
|
10月前
|
索引
LinkedList源码分析之 add 方法(二)
LinkedList源码分析之 add 方法(二)
57 0
|
10月前
|
缓存 安全 Java
ArrayList源码分析之add 方法
ArrayList源码分析之add 方法
97 0
|
存储 安全 算法
Java集合详解(List,Set,Map)
集合的背景 在没有集合类之前,实际上在Java语言里已经有一种方法可以存储对象,那就是数组。数组不仅可以存放基本数据类型也可以容纳属于同一种类型的对象。数组的操作是高效率的,但也有缺点。比如数组的长度是不可以变的,数组只能存放同一种类型的对象(或者说对象的引用)。
158 0
|
Java
Java基础——List、Set、Map的简单操作与遍历
Java基础——List、Set、Map的简单操作与遍历
72 0