ArrayList源码

1.无参构造

  1. ArrayList arrayList = new ArrayList();
  2. public ArrayList() {
  3. this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
  4. }

2.add方法

  1. public boolean add(E e) {
  2. ensureCapacityInternal(size + 1); // Increments modCount!!
  3. elementData[size++] = e;
  4. return true;
  5. }

3.ensureCapacityInternal

  1. private void ensureCapacityInternal(int minCapacity) {
  2. ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
  3. }

4.calculateCapacity

  1. private static int calculateCapacity(Object[] elementData, int minCapacity) {
  2. if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
  3. return Math.max(DEFAULT_CAPACITY, minCapacity);
  4. }
  5. return minCapacity;
  6. }

5.ensureExplicitCapacity

  1. private void ensureExplicitCapacity(int minCapacity) {
  2. modCount++;
  3. // overflow-conscious code
  4. if (minCapacity - elementData.length > 0)
  5. grow(minCapacity);
  6. }

6.grow

  1. private void grow(int minCapacity) {
  2. // overflow-conscious code
  3. int oldCapacity = elementData.length;
  4. int newCapacity = oldCapacity + (oldCapacity >> 1);
  5. if (newCapacity - minCapacity < 0)
  6. newCapacity = minCapacity;
  7. if (newCapacity - MAX_ARRAY_SIZE > 0)
  8. newCapacity = hugeCapacity(minCapacity);
  9. // minCapacity is usually close to size, so this is a win:
  10. elementData = Arrays.copyOf(elementData, newCapacity);
  11. }

7.Arrays.copyOf

  1. @SuppressWarnings("unchecked")
  2. public static <T> T[] copyOf(T[] original, int newLength) {
  3. return (T[]) copyOf(original, newLength, original.getClass());
  4. }

image.png

2.有参构造

  1. ArrayList arrayList = new ArrayList(8);
  1. public ArrayList(int initialCapacity) {
  2. if (initialCapacity > 0) {
  3. this.elementData = new Object[initialCapacity];
  4. } else if (initialCapacity == 0) {
  5. this.elementData = EMPTY_ELEMENTDATA;
  6. } else {
  7. throw new IllegalArgumentException("Illegal Capacity: "+
  8. initialCapacity);
  9. }
  10. }

HashSet源码

  1. HashSet hashSet = new HashSet();
  2. hashSet.add("java");
  3. hashSet.add("php");
  4. hashSet.add("java");
  5. System.out.println("hashset=" + hashSet);

1.hashmap

  1. public HashSet() {
  2. map = new HashMap<>();
  3. }

2.add

  1. public boolean add(E e) {
  2. return map.put(e, PRESENT)==null;
  3. }
  4. PRESENT hashSet的属性
  5. private static final Object PRESENT = new Object();

3.put

  1. public V put(K key, V value) {
  2. return putVal(hash(key), key, value, false, true);
  3. }

4.hash(key)

  1. static final int hash(Object key) {
  2. int h;
  3. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  4. }

5.putVal()

  1. //定义一些辅助变量
  2. final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
  3. boolean evict) {
  4. Node<K,V>[] tab; Node<K,V> p; int n, i;
  5. //table就是hashmap的属性类型是Node[]
  6. if ((tab = table) == null || (n = tab.length) == 0)
  7. n = (tab = resize()).length;
  8. //计算key的hash值的索引位置,并赋值给辅助变量p
  9. //判断是否为null
  10. //1.如果为空,表示没有存放元素,就创建一个Node(key="java",value="PRESENT")
  11. if ((p = tab[i = (n - 1) & hash]) == null)
  12. tab[i] = newNode(hash, key, value, null);
  13. else {
  14. //一个开发技巧提示 需要什么变量就写什么
  15. Node<K,V> e; K k;
  16. if (p.hash == hash && //如果当前索引位置链表对应的第一个元素和准备添加的keyhash值一样
  17. //满足下面两个条件之一:
  18. //1准备加入的key和 p 指向的node是同一个对象
  19. //2p指向的node节点的key的equals()和准备的key比较后相同
  20. ((k = p.key) == key || (key != null && key.equals(k))))
  21. e = p;
  22. //再判断key是不是一颗红黑树
  23. else if (p instanceof TreeNode)
  24. e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
  25. else {//如果table对应索引位置 已经是一个链表
  26. //1)依次和该链表的每一个元素比较后,都不相同,则加入到该链表的后面
  27. //立即判断是否达到8个节点 treeifyBin() table.length<64 扩容
  28. //树化时还进行判断
  29. //2 如果有相同的元素,就break
  30. for (int binCount = 0; ; ++binCount) {
  31. if ((e = p.next) == null) {
  32. p.next = newNode(hash, key, value, null);
  33. if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
  34. treeifyBin(tab, hash);
  35. break;
  36. }
  37. if (e.hash == hash &&
  38. ((k = e.key) == key || (key != null && key.equals(k))))
  39. break;
  40. p = e;
  41. }
  42. }
  43. if (e != null) { // existing mapping for key
  44. V oldValue = e.value;
  45. if (!onlyIfAbsent || oldValue == null)
  46. e.value = value;
  47. afterNodeAccess(e);
  48. return oldValue;
  49. }
  50. }
  51. ++modCount;
  52. if (++size > threshold)
  53. resize();
  54. afterNodeInsertion(evict);
  55. return null;
  56. }

6. resize()

  1. final Node<K,V>[] resize() {
  2. Node<K,V>[] oldTab = table;
  3. int oldCap = (oldTab == null) ? 0 : oldTab.length;
  4. int oldThr = threshold;
  5. int newCap, newThr = 0;
  6. if (oldCap > 0) {
  7. if (oldCap >= MAXIMUM_CAPACITY) {
  8. threshold = Integer.MAX_VALUE;
  9. return oldTab;
  10. }
  11. else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
  12. oldCap >= DEFAULT_INITIAL_CAPACITY)
  13. newThr = oldThr << 1; // double threshold
  14. }
  15. else if (oldThr > 0) // initial capacity was placed in threshold
  16. newCap = oldThr;
  17. else { // zero initial threshold signifies using defaults
  18. newCap = DEFAULT_INITIAL_CAPACITY;
  19. newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
  20. }
  21. if (newThr == 0) {
  22. float ft = (float)newCap * loadFactor;
  23. newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
  24. (int)ft : Integer.MAX_VALUE);
  25. }
  26. threshold = newThr;
  27. @SuppressWarnings({"rawtypes","unchecked"})
  28. Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
  29. table = newTab;
  30. if (oldTab != null) {
  31. for (int j = 0; j < oldCap; ++j) {
  32. Node<K,V> e;
  33. if ((e = oldTab[j]) != null) {
  34. oldTab[j] = null;
  35. if (e.next == null)
  36. newTab[e.hash & (newCap - 1)] = e;
  37. else if (e instanceof TreeNode)
  38. ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
  39. else { // preserve order
  40. Node<K,V> loHead = null, loTail = null;
  41. Node<K,V> hiHead = null, hiTail = null;
  42. Node<K,V> next;
  43. do {
  44. next = e.next;
  45. if ((e.hash & oldCap) == 0) {
  46. if (loTail == null)
  47. loHead = e;
  48. else
  49. loTail.next = e;
  50. loTail = e;
  51. }
  52. else {
  53. if (hiTail == null)
  54. hiHead = e;
  55. else
  56. hiTail.next = e;
  57. hiTail = e;
  58. }
  59. } while ((e = next) != null);
  60. if (loTail != null) {
  61. loTail.next = null;
  62. newTab[j] = loHead;
  63. }
  64. if (hiTail != null) {
  65. hiTail.next = null;
  66. newTab[j + oldCap] = hiHead;
  67. }
  68. }
  69. }
  70. }
  71. }
  72. return newTab;
  73. }

7.DEFAULT_INITIAL_CAPACITY

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