盗图一张,找不到原作者了,如有知道原链接的朋友,请告知,谢谢。
java的集合继承关系,第一个让我感觉有些头疼的JAVA知识点,初学时复杂的继承关系让我有点无所适从。今天开始重新梳理自己半年来的知识点,补充体系上的漏洞,个人水平还属于初级阶段,有概念错误或疏漏,也请各位朋友指正与补充,谢谢。
从List入手,依次梳理各常用数据结构的源码与原理,List下面常用的数据结构有ArrayList、LinkedList、Vector(线程安全,效率问题目前基本不用)。
ArrayList,动态数组,内部包含了一个数组,在此基础之上根据继承关系,封装了一组方法,常用的方法如下:
- ArrayList()
- ArrayList(int initialCapacity)
- ArrayList(Collection<? extends E> c)
- boolean add(E e)
- public Iterator<E> iterator()
ArrayList()
1 /** 2 * 构造一个空的ArrayList,初始容量为10. 3 */ 4 5 private static final int DEFAULT_CAPACITY = 10; 6 7 public ArrayList() { 8 this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; 9 }
ArrayList(int initialCapacity)
1 /** 2 * 以指定的容量创建一个ArrayList,其中每一个元素均为空 3 * 4 */ 5 public ArrayList(int initialCapacity) { 6 if (initialCapacity > 0) { 7 this.elementData = new Object[initialCapacity]; 8 } else if (initialCapacity == 0) { 9 this.elementData = EMPTY_ELEMENTDATA; 10 } else { 11 throw new IllegalArgumentException("Illegal Capacity: "+ 12 initialCapacity); 13 } 14 }
ArrayList(Collection<? extends E> c)
1 /** 2 * 以现有的集合作为初始值,创建一个新的ArrayList, 3 * 新的ArrayList为原集合的一个副本。 4 * 5 * @param c the collection whose elements are to be placed into this list 6 * @throws NullPointerException if the specified collection is null 7 */ 8 public ArrayList(Collection<? extends E> c) { 9 elementData = c.toArray(); 10 if ((size = elementData.length) != 0) { 11 // c.toArray might (incorrectly) not return Object[] (see 6260652) 12 if (elementData.getClass() != Object[].class) 13 elementData = Arrays.copyOf(elementData, size, Object[].class); 14 } else { 15 // replace with empty array. 16 this.elementData = EMPTY_ELEMENTDATA; 17 } 18 }
boolean add(E e)
ArrayList添加新元素,需要计算添加一个新元素后,当前ArrayList的容量是否足够。如果容量不够,需要将当前容量扩充至当前容量的1.5倍,如果超过虚拟机的最大限制,则截断详细如下:
1 /** 2 * Appends the specified element to the end of this list. 3 * 4 * @param e element to be appended to this list 5 * @return <tt>true</tt> (as specified by {@link Collection#add}) 6 */ 7 public boolean add(E e) { 8 ensureCapacityInternal(size + 1); // Increments modCount!! 9 elementData[size++] = e; 10 return true; 11 } 12 13 private void ensureCapacityInternal(int minCapacity) { 14 ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); 15 } 16 17 private void ensureExplicitCapacity(int minCapacity) { 18 modCount++; 19 20 // overflow-conscious code 21 if (minCapacity - elementData.length > 0) 22 grow(minCapacity); 23 } 24 25 /** 26 * Increases the capacity to ensure that it can hold at least the 27 * number of elements specified by the minimum capacity argument. 28 * 29 * @param minCapacity the desired minimum capacity 30 */ 31 private void grow(int minCapacity) { 32 // overflow-conscious code 33 int oldCapacity = elementData.length; 34 //容量扩充至当前的1.5倍,如果依然容纳不下实际元素数量,则将实际元素数量作为新的数组的容量,如果 35 int newCapacity = oldCapacity + (oldCapacity >> 1); 36 if (newCapacity - minCapacity < 0) 37 newCapacity = minCapacity; 38 if (newCapacity - MAX_ARRAY_SIZE > 0) 39 newCapacity = hugeCapacity(minCapacity); 40 // 创建新数组的拷贝 41 elementData = Arrays.copyOf(elementData, newCapacity); 42 } 43 44 add(E e)
public Iterator<E> iterator():返回一个Iterator类型的内部类对象,该对象包含了可以操作ArrayList对象的一些Iterator方法,入next、hasNext等方法
1 public Iterator<E> iterator() { 2 return new Itr(); 3 } 4 5 /** 6 * Returns an iterator over the elements in this list in proper sequence. 7 * 8 * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>. 9 * 10 * @return an iterator over the elements in this list in proper sequence 11 */ 12 public Iterator<E> iterator() { 13 return new Itr(); //创建一个新的内部类对象,该对象包含了对ArrayList对象的常用操作方法,next()、hasNext()、remove()等方法 14 } 15 16 /** 17 * An optimized version of AbstractList.Itr 18 */ 19 private class Itr implements Iterator<E> { 20 int cursor; // 当前被操作的元素,默认为0 21 int lastRet = -1; // 上一个被操作的元素,如果没有则为-1(初始时或上一个元素被删除时,则为0) 22 int expectedModCount = modCount; 23 24 public boolean hasNext() { 25 return cursor != size; 26 } 27 28 @SuppressWarnings("unchecked") 29 public E next() { 30 checkForComodification(); 31 int i = cursor; 32 if (i >= size) 33 throw new NoSuchElementException(); 34 Object[] elementData = ArrayList.this.elementData; 35 if (i >= elementData.length) 36 throw new ConcurrentModificationException(); 37 cursor = i + 1; 38 return (E) elementData[lastRet = i]; 39 } 40 41 public void remove() { 42 if (lastRet < 0) 43 throw new IllegalStateException(); 44 checkForComodification(); 45 46 try { 47 ArrayList.this.remove(lastRet); 48 cursor = lastRet; 49 lastRet = -1; 50 expectedModCount = modCount; 51 } catch (IndexOutOfBoundsException ex) { 52 throw new ConcurrentModificationException(); 53 } 54 } 55 }
以上是ArrayList中常用且典型的方法源码,理解上面的源码有助于帮助我们理解ArrayList的工作原理和特点。ArrayList在集合中是比较简单,但是非常常用的数据结构,了解了ArrayList可以让我们在合适的场景去使用它。