@Testpublicvoidtest_ArrayList_addFirst(){
ArrayList<Integer> list =newArrayList<Integer>();long startTime = System.currentTimeMillis();for(int i =0; i <10000000; i++){
list.add(0, i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}@Testpublicvoidtest_LinkedList_addFirst(){
LinkedList<Integer> list =newLinkedList<Integer>();long startTime = System.currentTimeMillis();for(int i =0; i <10000000; i++){
list.addFirst(i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}
voidlinkLast(E e){final Node<E> l = last;final Node<E> newNode =newNode<>(l, e, null);
last = newNode;if(l == null)
first = newNode;else
l.next = newNode;
size++;
modCount++;}
与头插代码相比几乎没有什么区别,只是first换成last
耗时点只是在创建节点上,Node<E>
2.2.2 验证
ArrayList、LinkeList,尾插源码验证
@Testpublicvoidtest_ArrayList_addLast(){
ArrayList<Integer> list =newArrayList<Integer>();long startTime = System.currentTimeMillis();for(int i =0; i <10000000; i++){
list.add(i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}@Testpublicvoidtest_LinkedList_addLast(){
LinkedList<Integer> list =newLinkedList<Integer>();long startTime = System.currentTimeMillis();for(int i =0; i <1000000; i++){
list.addLast(i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}
publicvoidadd(int index, E element){checkPositionIndex(index);if(index == size)linkLast(element);elselinkBefore(element,node(index));}
位置定位node(index):
Node<E>node(int index){// assert isElementIndex(index);if(index <(size >>1)){
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;}}
size >> 1,这部分的代码判断元素位置在左半区间,还是右半区间,在进行循环查找。
执行插入:
voidlinkBefore(E e, Node<E> succ){// assert succ != null;final Node<E> pred = succ.prev;final Node<E> newNode =newNode<>(pred, e, succ);
succ.prev = newNode;if(pred == null)
first = newNode;else
pred.next = newNode;
size++;
modCount++;}
找到指定位置插入的过程就比较简单了,与头插、尾插,相差不大。
整个过程可以看到,插入中比较耗时的点会在遍历寻找插入位置上。
2.3.2 验证
ArrayList、LinkeList,中间插入源码验证
@Testpublicvoidtest_ArrayList_addCenter(){
ArrayList<Integer> list =newArrayList<Integer>();long startTime = System.currentTimeMillis();for(int i =0; i <10000000; i++){
list.add(list.size()>>1, i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}@Testpublicvoidtest_LinkedList_addCenter(){
LinkedList<Integer> list =newLinkedList<Integer>();long startTime = System.currentTimeMillis();for(int i =0; i <1000000; i++){
list.add(list.size()>>1, i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}
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;}
这一部分是元素定位,和unlink(x)解链。循环查找对应的元素,这部分没有什么难点。
unlink(x)解链
E unlink(Node<E> x){// assert x != null;final E element = x.item;final Node<E> next = x.next;final Node<E> prev = x.prev;if(prev == null){
first = next;}else{
prev.next = next;
x.prev = null;}if(next == null){
last = prev;}else{
next.prev = prev;
x.next = null;}
x.item = null;
size--;
modCount++;return element;}
int xx =0;@Beforepublicvoidinit(){for(int i =0; i <10000000; i++){
list.add(i);}}
4.1 普通for循环
@Testpublicvoidtest_LinkedList_for0(){long startTime = System.currentTimeMillis();for(int i =0; i < list.size(); i++){
xx += list.get(i);}
System.out.println("耗时:"+(System.currentTimeMillis()- startTime));}