1 | public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable |
1 2 3 4 | // 保存ArrayList中数据的数组 private transient Object[] elementData; // ArrayList中实际数据的数量 private int size; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | // ArrayList带容量大小的构造函数。 public ArrayList(int initialCapacity) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity); // 新建一个数组 this.elementData = new Object[initialCapacity]; } // ArrayList构造函数。默认容量是10。 public ArrayList() { this(10); } // 构造一个包含指定元素的list,这些元素的是按照Collection的迭代器返回的顺序排列的 public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); size = elementData.length; if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /** * 添加一个元素 */ public boolean add(E e) { // 进行扩容检查 ensureCapacity( size + 1); // Increments modCount // 将e增加至list的数据尾部,容量+1 elementData[size ++] = e; return true; } /** * 在指定位置添加一个元素 */ public void add(int index, E element) { // 判断索引是否越界,这里会抛出多么熟悉的异常。。。 if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: "+index+", Size: " +size); // 进行扩容检查 ensureCapacity( size+1); // Increments modCount // 对数组进行复制处理,目的就是空出index的位置插入element,并将index后的元素位移一个位置 System. arraycopy(elementData, index, elementData, index + 1, size - index); // 将指定的index位置赋值为element elementData[index] = element; // list容量+1 size++; } /** * 增加一个集合元素 */ public boolean addAll(Collection<? extends E> c) { //将c转换为数组 Object[] a = c.toArray(); int numNew = a.length ; //扩容检查 ensureCapacity( size + numNew); // Increments modCount //将c添加至list的数据尾部 System. arraycopy(a, 0, elementData, size, numNew); //更新当前容器大小 size += numNew; return numNew != 0; } /** * 在指定位置,增加一个集合元素 */ public boolean addAll(int index, Collection<? extends E> c) { if (index > size || index < 0) throw new IndexOutOfBoundsException( "Index: " + index + ", Size: " + size); Object[] a = c.toArray(); int numNew = a.length ; ensureCapacity( size + numNew); // Increments modCount // 计算需要移动的长度(index之后的元素个数) int numMoved = size - index; // 数组复制,空出第index到index+numNum的位置,即将数组index后的元素向右移动numNum个位置 if (numMoved > 0) System. arraycopy(elementData, index, elementData, index + numNew, numMoved); // 将要插入的集合元素复制到数组空出的位置中 System. arraycopy(a, 0, elementData, index, numNew); size += numNew; return numNew != 0; } /** * 数组容量检查,不够时则进行扩容 */ public void ensureCapacity( int minCapacity) { modCount++; // 当前数组的长度 int oldCapacity = elementData .length; // 最小需要的容量大于当前数组的长度则进行扩容 if (minCapacity > oldCapacity) { Object oldData[] = elementData; // 新扩容的数组长度为旧容量的1.5倍+1 int newCapacity = (oldCapacity * 3)/2 + 1; // 如果新扩容的数组长度还是比最小需要的容量小,则以最小需要的容量为长度进行扩容 if (newCapacity < minCapacity) newCapacity = minCapacity; // minCapacity is usually close to size, so this is a win: // 进行数据拷贝,Arrays.copyOf底层实现是System.arrayCopy() elementData = Arrays.copyOf( elementData, newCapacity); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | /** * 根据索引位置删除元素 */ public E remove( int index) { // 数组越界检查 RangeCheck(index); modCount++; // 取出要删除位置的元素,供返回使用 E oldValue = (E) elementData[index]; // 计算数组要复制的数量 int numMoved = size - index - 1; // 数组复制,就是将index之后的元素往前移动一个位置 if (numMoved > 0) System. arraycopy(elementData, index+1, elementData, index, numMoved); // 将数组最后一个元素置空(因为删除了一个元素,然后index后面的元素都向前移动了,所以最后一个就没用了),好让gc尽快回收 // 不要忘了size减一 elementData[--size ] = null; // Let gc do its work return oldValue; } /** * 根据元素内容删除,只删除匹配的第一个 */ public boolean remove(Object o) { // 对要删除的元素进行null判断 // 对数据元素进行遍历查找,知道找到第一个要删除的元素,删除后进行返回,如果要删除的元素正好是最后一个那就惨了,时间复杂度可达O(n) 。。。 if (o == null) { for (int index = 0; index < size; index++) // null值要用==比较 if (elementData [index] == null) { fastRemove(index); return true; } } else { for (int index = 0; index < size; index++) // 非null当然是用equals比较了 if (o.equals(elementData [index])) { fastRemove(index); return true; } } return false; } /* * Private remove method that skips bounds checking and does not * return the value removed. */ private void fastRemove(int index) { modCount++; // 原理和之前的add一样,还是进行数组复制,将index后的元素向前移动一个位置,不细解释了, int numMoved = size - index - 1; if (numMoved > 0) System. arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size ] = null; // Let gc do its work } /** * 数组越界检查 */ private void RangeCheck(int index) { if (index >= size ) throw new IndexOutOfBoundsException( "Index: "+index+", Size: " +size); } |
1 2 3 4 5 6 7 8 9 10 11 | /** * 将底层数组的容量调整为当前实际元素的大小,来释放空间。 */ public void trimToSize() { modCount++; // 当前数组的容量 int oldCapacity = elementData .length; // 如果当前实际元素大小 小于 当前数组的容量,则进行缩容 if (size < oldCapacity) { elementData = Arrays.copyOf( elementData, size ); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * 将指定位置的元素更新为新元素 */ public E set( int index, E element) { // 数组越界检查 RangeCheck(index); // 取出要更新位置的元素,供返回使用 E oldValue = (E) elementData[index]; // 将该位置赋值为行的元素 elementData[index] = element; // 返回旧元素 return oldValue; } |
1 2 3 4 5 6 7 8 | /** * 查找指定位置上的元素 */ public E get( int index) { RangeCheck(index); return (E) elementData [index]; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | /** * Returns <tt>true</tt> if this list contains the specified element. * More formally, returns <tt>true</tt> if and only if this list contains * at least one element <tt>e</tt> such that * <tt>(o==null ? e==null : o.equals(e))</tt>. * * @param o element whose presence in this list is to be tested * @return <tt> true</tt> if this list contains the specified element */ public boolean contains(Object o) { return indexOf(o) >= 0; } /** * Returns the index of the first occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the lowest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ public int indexOf(Object o) { if (o == null) { for (int i = 0; i < size; i++) if (elementData ==null) return i; } else { for (int i = 0; i < size; i++) if (o.equals(elementData )) return i; } return -1; } /** * Returns the index of the last occurrence of the specified element * in this list, or -1 if this list does not contain the element. * More formally, returns the highest index <tt>i</tt> such that * <tt>(o==null ? get(i)==null : o.equals(get(i)))</tt>, * or -1 if there is no such index. */ public int lastIndexOf(Object o) { if (o == null) { for (int i = size-1; i >= 0; i--) if (elementData ==null) return i; } else { for (int i = size-1; i >= 0; i--) if (o.equals(elementData )) return i; } return -1; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * Returns the number of elements in this list. * * @return the number of elements in this list */ public int size() { return size ; } /** * Returns <tt>true</tt> if this list contains no elements. * * @return <tt> true</tt> if this list contains no elements */ public boolean isEmpty() { return size == 0; } |
1 2 3 4 5 | Integer value = null; Iterator iter = list.iterator(); while (iter.hasNext()) { value = (Integer)iter.next(); } |
1 2 3 4 5 | Integer value = null; int size = list.size(); for (int i=0; i<size; i++) { value = (Integer)list.get(i); } |
1 2 3 4 | Integer value = null; for (Integer integ:list) { value = integ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import java.util.*; import java.util.concurrent.*; /* * @desc ArrayList遍历方式和效率的测试程序。 * * @author skywang */ public class ArrayListRandomAccessTest { public static void main(String[] args) { List list = new ArrayList(); for (int i=0; i<100000; i++) list.add(i); //isRandomAccessSupported(list); iteratorThroughRandomAccess(list) ; iteratorThroughIterator(list) ; iteratorThroughFor2(list) ; } private static void isRandomAccessSupported(List list) { if (list instanceof RandomAccess) { System.out.println("RandomAccess implemented!"); } else { System.out.println("RandomAccess not implemented!"); } } public static void iteratorThroughRandomAccess(List list) { long startTime; long endTime; startTime = System.currentTimeMillis(); for (int i=0; i<list.size(); i++) { list.get(i); } endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println("iteratorThroughRandomAccess:" + interval+" ms"); } public static void iteratorThroughIterator(List list) { long startTime; long endTime; startTime = System.currentTimeMillis(); for(Iterator iter = list.iterator(); iter.hasNext(); ) { iter.next(); } endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println("iteratorThroughIterator:" + interval+" ms"); } public static void iteratorThroughFor2(List list) { long startTime; long endTime; startTime = System.currentTimeMillis(); for(Object obj:list) ; endTime = System.currentTimeMillis(); long interval = endTime - startTime; System.out.println("iteratorThroughFor2:" + interval+" ms"); } } |
1 2 3 | iteratorThroughRandomAccess:3 ms iteratorThroughIterator:8 ms iteratorThroughFor2:5 ms |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | import java.util.*; /* * @desc ArrayList常用API的测试程序 * @author skywang * @email kuiwu-wang@163.com */ public class ArrayListTest { public static void main(String[] args) { // 创建ArrayList ArrayList list = new ArrayList(); // 将“” list.add("1"); list.add("2"); list.add("3"); list.add("4"); // 将下面的元素添加到第1个位置 list.add(0, "5"); // 获取第1个元素 System.out.println("the first element is: "+ list.get(0)); // 删除“3” list.remove("3"); // 获取ArrayList的大小 System.out.println("Arraylist size=: "+ list.size()); // 判断list中是否包含"3" System.out.println("ArrayList contains 3 is: "+ list.contains(3)); // 设置第2个元素为10 list.set(1, "10"); // 通过Iterator遍历ArrayList for(Iterator iter = list.iterator(); iter.hasNext(); ) { System.out.println("next is: "+ iter.next()); } // 将ArrayList转换为数组 String[] arr = (String[])list.toArray(new String[0]); for (String str:arr) System.out.println("str: "+ str); // 清空ArrayList list.clear(); // 判断ArrayList是否为空 System.out.println("ArrayList is empty: "+ list.isEmpty()); } } |
1 2 3 4 5 6 7 8 9 10 11 12 | the first element is: 5 Arraylist size=: 4 ArrayList contains 3 is: false next is: 5 next is: 10 next is: 2 next is: 4 str: 5 str: 10 str: 2 str: 4 ArrayList is empty: true |
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |