-
map.put 方法解析
// map.put 方法 不能存null的key和value // 不成立:map.put(null, null) map.put(null,Object) map.put(Object, null) // map.put 在这里没有如果put不满足的数值 会抛出异常 java.lang.NullPointerException public synchronized V put(K key, V value) { // Make sure the value is not null if (value == null) {// key也不能为null 可以为字符串: "",字符串""的 hash 为0 throw new NullPointerException(); } // Makes sure the key is not already in the hashtable. Entry<?,?> tab[] = table;//定义tab[] int hash = key.hashCode();//取key的hash值 int index = (hash & 0x7FFFFFFF) % tab.length;//取模运算 计算需要存储的位置 @SuppressWarnings("unchecked") Entry<K,V> entry = (Entry<K,V>)tab[index]; //确定当前位置是否已存在数据,hash存储会有数据碰撞的几率,这就是为什么说两个对象的 // hashcode相等,值却不一定相等的原因,例如: Aa 和 BB 的hashCode 都是2112 //循环判断当前需要存储的位置的entry是否为已存储的数据,hash表存储数据格式(数组与链表存储 //的结合) 成立则覆盖oldValue并返回old 不成立则继续循环下一个 for(; entry != null ; entry = entry.next) { // 判断是否是重复key数据put if ((entry.hash == hash) && entry.key.equals(key)) { V old = entry.value; entry.value = value; return old; } } addEntry(hash, key, value, index);//执行newEntry的add操作 return null; } // addEntry方法解析 执行数组的扩容操作以及add操作 private void addEntry(int hash, K key, V value, int index) { modCount++; Entry<?,?> tab[] = table;//定义tab[] //判断当前的存储数量是否超出或等于当前数组最大的容量阀值 if (count >= threshold) { // Rehash the table if the threshold is exceeded rehash();//执行扩容的方法 oldCP * 2 + 1 tab = table;//扩容之后的newTable hash = key.hashCode(); index = (hash & 0x7FFFFFFF) % tab.length;//取模计算需要存放的位置 } // Creates the new entry. @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>) tab[index];// 取当前位置是否存在oldEntry //执行Entry的链表存储结构先入的放到后面 //protected Entry(int hash, K key, V value, Entry<K,V> next) { //this.hash = hash; //this.key = key; //this.value = value; //this.next = next; //} tab[index] = new Entry<>(hash, key, value, e); count++; } // rehash() 方法 执行数组的扩容方法 oldCp * 2 + 1 @SuppressWarnings("unchecked") protected void rehash() { int oldCapacity = table.length;//定义oldCp Entry<?,?>[] oldMap = table;// 定义 oldMap 执行copy时使用 执行扩容之后的数组为table // overflow-conscious code int newCapacity = (oldCapacity << 1) + 1;// newCp 为 oldCp * 2 + 1 if (newCapacity - MAX_ARRAY_SIZE > 0) {// HashTable 的最大容量是MAX_ARRAY_SIZE if (oldCapacity == MAX_ARRAY_SIZE) // Keep running with MAX_ARRAY_SIZE buckets return; newCapacity = MAX_ARRAY_SIZE;// 定义newCp 为MAX_ARRAY_SIZE } Entry<?,?>[] newMap = new Entry<?,?>[newCapacity]; modCount++; // 最大容量阀值为 newCp * 0.75(默认) 或者 MAX_ARRAY_SIZE + 1 threshold = (int)Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1); table = newMap;// 从新定义table 执行copy操作 for (int i = oldCapacity ; i-- > 0 ;) {// 循环执行数据的copy // 执行 散列表数据结构的 copy for (Entry<K,V> old = (Entry<K,V>)oldMap[i] ; old != null ; ) { Entry<K,V> e = old;// 将oldEntry 赋值 给e old = old.next;// 从新定义oldEntry 为old.next int index = (e.hash & 0x7FFFFFFF) % newCapacity;// 取模计算新数组的存放位置 e.next = (Entry<K,V>)newMap[index];//防止数据丢失 链表存储结构 先入后出 newMap[index] = e;// 执行数据的存放 } } }
-
map.get(key) 方法解析
// map.get() 方法源码解析 @SuppressWarnings("unchecked") public synchronized V get(Object key) { Entry<?,?> tab[] = table;// 定义tab[] int hash = key.hashCode();//取key的hashCode int index = (hash & 0x7FFFFFFF) % tab.length;//与运算 取模计算存储的位置 for (Entry<?,?> e = tab[index] ; e != null ; e = e.next) {// 循环对比取值 if ((e.hash == hash) && e.key.equals(key)) {// 判断是否匹配 return (V)e.value;//成功返回value } } return null;//无匹配数据返回null }
-
map.putAll(Map<? extends K, ? extends V> m) 方法解析
// map.putAll() 方法源码解析 // 循环执行map数据的put操作 public synchronized void putAll(Map<? extends K, ? extends V> t) { for (Map.Entry<? extends K, ? extends V> e : t.entrySet()) put(e.getKey(), e.getValue());// put源码 }
-
map.remove(key) 方法解析
// map.remove(Object key) 方法源码解析 // remove 的方法 是先执行get(key) 方法 在执行数据的remove public synchronized V remove(Object key) { Entry<?,?> tab[] = table;//定义tab[] int hash = key.hashCode();//去key的hashCode int index = (hash & 0x7FFFFFFF) % tab.length;//与运算 取模 计算数据的存储位置 @SuppressWarnings("unchecked") Entry<K,V> e = (Entry<K,V>)tab[index];// 找到需要remove的链表数据结构对象 //循环对比 找到需要remove的对象 for(Entry<K,V> prev = null ; e != null ; prev = e, e = e.next) { if ((e.hash == hash) && e.key.equals(key)) {//判断条件是否成立 modCount++; if (prev != null) {//如果prev != null 链表数据结构remove 只需要移动指针操作 prev.next = e.next; } else { tab[index] = e.next;//当前链表的first位置,移动指针操作 } count--; V oldValue = e.value; e.value = null;// 设置为null 方便回收 return oldValue;//返回remove的value值 } } return null;// 不匹配返回null }
Map的实现类Hashtable各种方法源码解析
最新推荐文章于 2023-03-17 22:59:22 发布