• HashMap源码分析


    HashMap源码分析

    •  static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
      

    hasmap默认初始容量大小 16

    •  static final int MAXIMUM_CAPACITY = 1 << 30;
      

    hashmap数组最大容量 1<<30 2的30次方

    • static final float DEFAULT_LOAD_FACTOR = 0.75f;
      

    默认加载因子 若数组容量为16 当添加超过12时 要扩容 每次扩容为上次的2倍

    • static final int MIN_TREEIFY_CAPACITY = 64;
      static final int TREEIFY_THRESHOLD = 8;
      

    当数组长度大于64,链表长度大于8时 链表转为红黑树

    • static final int UNTREEIFY_THRESHOLD = 6;
      

    当红黑树元素个数小于6时,转为链表

    • transient Node<K,V>[] table;
      

    哈希表中的数组

    • transient int size;
      

    元素个数

    • public HashMap() {
              this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
          //因此  刚创建HashMap对象时,  size = 0, table = null
          //目的  节省空间
          }
      

    无参构造函数

    1. put()方法分析:

      public V put(K key, V value) {
              return putVal(hash(key), key, value, false, true);
          }
      
      final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                         boolean evict) {
              Node<K,V>[] tab; Node<K,V> p; int n, i;
              if ((tab = table) == null || (n = tab.length) == 0)
                  n = (tab = resize()).length;
              if ((p = tab[i = (n - 1) & hash]) == null)
                  tab[i] = newNode(hash, key, value, null);
              else {
                  Node<K,V> e; K k;
                  if (p.hash == hash &&
                      ((k = p.key) == key || (key != null && key.equals(k))))
                      e = p;
                  else if (p instanceof TreeNode)
                      e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                  else {
                      for (int binCount = 0; ; ++binCount) {
                          if ((e = p.next) == null) {
                              p.next = newNode(hash, key, value, null);
                              if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                  treeifyBin(tab, hash);
                              break;
                          }
                          if (e.hash == hash &&
                              ((k = e.key) == key || (key != null && key.equals(k))))
                              break;
                          p = e;
                      }
                  }
                  if (e != null) { // existing mapping for key
                      V oldValue = e.value;
                      if (!onlyIfAbsent || oldValue == null)
                          e.value = value;
                      afterNodeAccess(e);
                      return oldValue;
                  }
              }
              ++modCount;
              if (++size > threshold)
                  resize();
              afterNodeInsertion(evict);
              return null;
          }
      
      static final int hash(Object key) {
              int h;
              return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
          }
      
          final Node<K,V>[] resize() {
              Node<K,V>[] oldTab = table;
              int oldCap = (oldTab == null) ? 0 : oldTab.length;
              int oldThr = threshold;
              int newCap, newThr = 0;
              if (oldCap > 0) {
                  if (oldCap >= MAXIMUM_CAPACITY) {
                      threshold = Integer.MAX_VALUE;
                      return oldTab;
                  }
                  else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                           oldCap >= DEFAULT_INITIAL_CAPACITY)
                      newThr = oldThr << 1; // double threshold
              }
              else if (oldThr > 0) // initial capacity was placed in threshold
                  newCap = oldThr;
              else {               // zero initial threshold signifies using defaults
                  newCap = DEFAULT_INITIAL_CAPACITY;
                  newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
              }
              if (newThr == 0) {
                  float ft = (float)newCap * loadFactor;
                  newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
                            (int)ft : Integer.MAX_VALUE);
              }
              threshold = newThr;
              @SuppressWarnings({"rawtypes","unchecked"})
                  Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
              table = newTab;
              if (oldTab != null) {
                  for (int j = 0; j < oldCap; ++j) {
                      Node<K,V> e;
                      if ((e = oldTab[j]) != null) {
                          oldTab[j] = null;
                          if (e.next == null)
                              newTab[e.hash & (newCap - 1)] = e;
                          else if (e instanceof TreeNode)
                              ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
                          else { // preserve order
                              Node<K,V> loHead = null, loTail = null;
                              Node<K,V> hiHead = null, hiTail = null;
                              Node<K,V> next;
                              do {
                                  next = e.next;
                                  if ((e.hash & oldCap) == 0) {
                                      if (loTail == null)
                                          loHead = e;
                                      else
                                          loTail.next = e;
                                      loTail = e;
                                  }
                                  else {
                                      if (hiTail == null)
                                          hiHead = e;
                                      else
                                          hiTail.next = e;
                                      hiTail = e;
                                  }
                              } while ((e = next) != null);
                              if (loTail != null) {
                                  loTail.next = null;
                                  newTab[j] = loHead;
                              }
                              if (hiTail != null) {
                                  hiTail.next = null;
                                  newTab[j + oldCap] = hiHead;
                              }
                          }
                      }
                  }
              }
              return newTab;
          }
      
    • HashSet源码
    public HashSet() {
            map = new HashMap<>();
        }
    
    //add方法
    public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
    
  • 相关阅读:
    CodeForces 514B
    CodeForces 514A
    UVa 818
    HDU 1003
    UVa百题总结
    UVa 11526
    UVa 12412
    UVa 211
    UVa 1587
    UVa 225 – Golygons [DFS+剪枝]
  • 原文地址:https://www.cnblogs.com/qiudajiang/p/13267727.html
Copyright © 2020-2023  润新知