集合相关知识总结:
集合【3】 — ArrayList和LinkedList区别与联系(面试题)
ArrayList和LinkedList区别与联系
1. ArrayList和LinkedList存储方式不同
- ArrayList继承Object , Ojbect[]是一个数组,它就是ArrayList用于存储元素的容器,即是Ojbect[]数组中的一个元素。
- LinkedList有一个核心的内部类Node(静态内部类),没调用一次add()方法就会 new一个Node对象,然后建立前一个和下一个的关联(链子)
2. ArrayList和LinkedList都有add() , get(), remove() 方法, 但原理源码不同
进行压力单元测试,20W次 (运行速度不同,说明原理不同,性能不同,从源码分析)
集合 | add()平均耗时 | get()平均耗时 | remove()平均耗时 |
---|---|---|---|
ArrayList | 9ms | 10ms | 3s |
LinkedList | 10ms | 27.5s | 16ms |
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import org.junit.Test;
/**
* @author lexiaowu
* 对ArrayList和LinkedList做压力测试(add()、get()、remove()),20W次
*/
public class Test20W {
/**
* 定义 ArrayList和LinkedList
*/
List<Integer> array = new ArrayList<>();
List<Integer> linked = new LinkedList<>();
/**
* 定义常量次数
*/
private final static int SIZE = 200000;
/**
* 测试add()
*/
@Test
public void addArrayList(){
for (int i = 0; i < SIZE; i++) {
array.add(i);
}
}
@Test
public void addLinkedList(){
for (int i = 0; i < SIZE; i++) {
linked.add(i);
}
}
/**
* 测试get()
*/
@Test
public void getArrayList(){
this.addArrayList();
for(int i=0;i<SIZE;i++){
array.get(i);
}
}
@Test
public void getLinkedList(){
this.addLinkedList();
for(int i=0;i<SIZE;i++){
linked.get(i);
}
}
/**
* 测试remove()
*/
@Test
public void removeArrayList(){
this.addArrayList();
for(int i=0;i<SIZE;i++){
array.remove(0);
}
}
@Test
public void removeLinkedList(){
this.addLinkedList();
for(int i=0;i<SIZE;i++){
linked.remove(0);
}
}
}
测试完以后,为什么会是这样的结果捏???
【分析】
2.1 add()
- ArrayList的add()方法比LinkedList稍快一丢丢?
ArrayList把新元素按照下标放入数组,
LinkedList每次add()都要创建Node对象,还要建立前一个和后一个的关联,所以LinkedList的add()方法稍慢。
2.2 get()
- ArrayList的get()方法比LinkedList快好多倍撒?
ArrayList本质是数组,使用下标进行get(),所以快,
LinkedList没有下标,如何get()? --> 使用二分查找(折半查找),使用循环逐个遍历,所以效率低下。
2.3 remove()
- LinkedList删除首部元素比ArrayList快很多呦?
ArrayList删除首部,将后面的元素做一次搬家,所有元素都要往前移一次,
LinkedList删除首部,只需要将链表的关系解除(将链子砍断),一旦没有任何引用指向该元素,JVM的GC就会将其占用的内存回收掉。
总结:
-
经常插入和经常删除使用LinkedList,不要使用LinkedList做查找,效率低
-
经常插入和经常查找使用ArrayList
-
ArrayList使用频率远远高于LinkedList