// overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } privatevoidgrow(int minCapacity){ // 计算当前ArrayList大小 int oldCapacity = elementData.length; //这里我们可以看出,ArrayList每次扩容是增加50%,oldCapacity >> 1是指往左移一位,也就是除以2 int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); } //根据下标index获取元素值 public E get(int index){ rangeCheck(index);//检查小标是否越界 return elementData(index); } //将index位置的值设为element,并返回原来的值 public E set(int index, E element){ rangeCheck(index);
ensureCapacityInternal(size + 1); // Increments modCount!! //将index以及index之后的数据复制到index+1的位置往后,即从index开始向后挪了一位 System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; } //根据指定的index,删除元素 public E remove(int index){ rangeCheck(index);
modCount++; E oldValue = elementData(index);
int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work
if (index < (size >> 1)) {//如果index<(size/2),则从前找 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else {//否则从末尾往前找 Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } } //直接删除某个元素 publicbooleanremove(Object o){ if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x); returntrue; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x); returntrue; } } } returnfalse; } //根据下标查询某个元素 public E get(int index){ checkElementIndex(index);//检查下标是否越界 return node(index).item;//可以看第一个node的方法,其中有查询 } //设置index位置处的值为element public E set(int index, E element){ checkElementIndex(index); Node<E> x = node(index); E oldVal = x.item; x.item = element; return oldVal; } //在下标index位置处新增element publicvoidadd(int index, E element){ checkPositionIndex(index);
if (index == size)//index是末尾,则在末尾新增一个 linkLast(element); else//这里的插入需要先去查询相应的位置,这会导致性能降低 linkBefore(element, node(index)); }
publicstaticvoidmain(String[] args){ List<Integer> array = new ArrayList<>(); LinkedList<Integer> linked = new LinkedList<>(); //首先分别给两者插入10000条数据 for (int i = 0; i < 100000; i++) { array.add(i); linked.add(i); } //获得两者随机访问的时间 System.out.println("array get cost time:" + getTime(array)); System.out.println("linked get cost time:" + getTime(linked));
//获得在中间插入数据的时间 System.out.println("array insert in first cost time:" + insertArrayListAtFirstTime(array)); System.out.println("linked insert cost in first time:" + insertLinkedListAtFirstTime(linked));
//获得在中间插入数据的时间 System.out.println("array insert in middle cost time:" + insertInMiddleTime(array)); System.out.println("linked insert cost in middle time:" + insertInMiddleTime(linked));
//获得尾部插入数据的时间 System.out.println("array insert at last cost time:" + insertAtLastTime(array)); System.out.println("linked insert cost at last time:" + insertAtLastTime(linked)); }
//头插 publicstaticlonginsertArrayListAtFirstTime(List<Integer> list){ int num = 100000; long time = System.currentTimeMillis(); for (int i = 1; i < num; i++) { list.add(0, i); } return System.currentTimeMillis() - time; }
//头插 publicstaticlonginsertLinkedListAtFirstTime(LinkedList<Integer> list){ int num = 100000; long time = System.currentTimeMillis(); for (int i = 1; i < num; i++) { list.addFirst(i); } return System.currentTimeMillis() - time; }
//中间插入数据 publicstaticlonginsertInMiddleTime(List<Integer> list){ int num = 10000000; //表示要插入的数据量 long time = System.currentTimeMillis(); for (int i = 1; i < num; i++) { list.add(list.size() >> 1, i); } return System.currentTimeMillis() - time; }
//尾插 publicstaticlonginsertAtLastTime(List<Integer> list){ int num = 1000000; //表示要插入的数据量 long time = System.currentTimeMillis(); for (int i = 1; i < num; i++) { list.add(i); } return System.currentTimeMillis() - time; }
publicstaticlonggetTime(List<Integer> list){ long time = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { int index = Collections.binarySearch(list, list.get(i)); if (index != i) { System.out.println("ERROR!"); } } return System.currentTimeMillis() - time; }
这个是运行时间:
1 2 3 4 5 6 7 8 9 10 11
array get cost time:6 linked get cost time:4170
array insert in first cost time:2927 linked insert cost in first time:4
array insert in middle cost time:1887 linked insert cost in middle time:124
array insert at last cost time:23 linked insert cost at last time:92