一般大家都知道ArrayList和LinkedList大致区别
- ArrayList是基于动态数组,LinkedList是基于链表
- 对于随即访问get操作,Arraylist要优于LinkedList,因为LinkedListt需要移动指针
- 对于新增和删除add和removeLinkedList要占优势因为ArrayList需要移动元素
但是事实真的是这样吗?我们来看一段代码
ArrayList<Integer> arrayList = new ArrayList<>();
LinkedList<Integer> linkedList = new LinkedList<>();
int number = 10000000;
new Thread(()->{
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < number; i++) {
arrayList.add(i);
}
stopWatch.stop();
System.out.println("arrayList插入"+number+"条数据的时候"+stopWatch.prettyPrint());
}
).start();
new Thread(()->{
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < number; i++) {
linkedList.add(i);
}
stopWatch.stop();
System.out.println("linkedList插入"+number+"条数据的时候"+stopWatch.prettyPrint());
}
).start();
执行结果:这里我创建了两个线程分别来执行两个集合的add操作,在数据量1千万的时候我们看到好像并没有什么差别,而且arraylist反而还快点那么我们略微修改下代码,给arraylist一个初始的容量1000,代码如下
ArrayList<Integer> arrayList = new ArrayList<>(1000);
LinkedList<Integer> linkedList = new LinkedList<>();
int number = 10000000;
new Thread(()->{
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < number; i++) {
arrayList.add(i);
}
stopWatch.stop();
System.out.println("arrayList插入"+number+"条数据的时候"+stopWatch.prettyPrint());
}
).start();
new Thread(()->{
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < number; i++) {
linkedList.add(i);
}
stopWatch.stop();
System.out.println("linkedList插入"+number+"条数据的时候"+stopWatch.prettyPrint());
}
).start();
}
执行结果:在尾部执行add操作的时候,其实ArrayList其实效率是比linkedList快的,主要是在他们各自的add方法上的问题
arrayList的add方法步骤:
//size记录的是ArrayList的大小(它包含的元素数),并加让当前seiz+1
ensureCapacityInternal(size + 1);
//对组大小进行判断或扩容完成后,将新的元素添加大最后一个位置
elementData[size++] = e;
//返回true,表示添加成功
return true;
linkedList的add方法步骤:
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
//新建一个node节点
last = newNode;
if (l == null)
first = newNode;
else
//放在最后一个节点
l.next = newNode;
size++;
modCount++;
}
结论:如果在集合最后一位添加元素的时候,ArrayList只需要在最后一位上添加元素,主要的耗时都在数组扩容上,而LinkedList则需要一一遍历到最后一个节点上再添加元素,所以在我们给ArrayList一个非常大的初始容量的时候,大大的减少扩容的次数,这样在大数据量添加的时候ArrayList效率是LinkedList两倍不止