标签:元素 插入数据 基本 sys alt 添加元素 复制 mil 增加
/**
* 顺序插
*/
@Test
public void test() {
ArrayList<String> arr = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
arr.add("a");
}
long end = System.currentTimeMillis();
System.out.println("arrylist time:" + (end - start));
LinkedList<String> link = new LinkedList<>();
start = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
link.addLast("a");
}
end = System.currentTimeMillis();
System.out.println("linkedlist time:" + (end - start));
}
可以发现,结果与我们预计的相同。LinkedList插入速度快于ArrayList。
但是,我们将插入的数值加大到100w。
ArrayList的插入速度居然快于LinkedList,这是为什么呢?
因为ArrayList每次需要扩容的话,新数组是旧数组容量的1.5倍,再使用Arrays.copyOf()将旧数组中的元素复制到新数组,不需要扩容的话则直接插入。插入数据的大部分时间用来复制数组。
而LinkedList每次添加元素需要构建节点,再将新节点插入队尾。插入数据的大部分时间用来构建节点。
当元素很少的时候,构建节点所需的时间少于数组复制的时间,但是当元素急剧增多的时候,ArrayList数组扩容到足够大,已经足够添加所有元素,此时不需要再次扩容,所以几乎没有复制数组的时间。而LinkedList链表添加时间随着元素的不断增多而增多。
/**
* 头插入 array < linked
*/
@Test
public void test1() {
ArrayList<String> arr = new ArrayList<>();
long start = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
arr.add(0, "a");
}
long end = System.currentTimeMillis();
System.out.println("arrylist time:" + (end - start));
LinkedList<String> link = new LinkedList<>();
start = System.currentTimeMillis();
for (int i = 0; i < 200000; i++) {
link.add(0, "a");
}
end = System.currentTimeMillis();
System.out.println("linkedlist time:" + (end - start));
}
这是因为ArrayList每次插入新元素都要将后面所有元素向后移动一位,这是ArrayList插入最坏的情况。
/**
* 中间插 1.数据量低于150w LinkedList 》 ArrayList
* 2.数据量大于150w ArrayList 《 LinkedList
*/
@Test
public void test3() {
ArrayList<String> arr = new ArrayList<>();
for (int i = 0; i < 1500000; i++) {
arr.add("a");
}
long start = System.currentTimeMillis();
for (int i = 0; i < arr.size() / 2; i++) {
arr.add("a");
}
long end = System.currentTimeMillis();
System.out.println("arrylist time:" + (end - start));
LinkedList<String> link = new LinkedList<>();
for (int i = 0; i < 1500000; i++) {
link.add("a");
}
start = System.currentTimeMillis();
for (int i = 0; i < link.size() / 2; i++) {
link.add("a");
}
end = System.currentTimeMillis();
System.out.println("linkedlist time:" + (end - start));
}
当插入的数据量是140w时
LinkedList小胜ArrayList一筹。但当数据量增加到150w时
LinkedList的插入所需时间急剧增多,而ArrayList所需时间基本保持不变,可以认为150w是两者的转折点。
LinkedList在指定位置插入需要先移动移动指针到指定位置,虽然将链表分成前后两部分进行查找,但是速度明显慢于数组,这在随机插入中表现更加明显。
/**
* 随机插入 array >> linked
*/
@Test
public void test4() {
List<String> list = new ArrayList<>();
Random random = new Random();
long start = System.currentTimeMillis();
for (int i = 1; i < 50000; i++) {
int x = random.nextInt(i);
list.add(x, "a");
}
long end = System.currentTimeMillis();
System.out.println("arrayList insert time " + (end - start));
List<String> list1 = new LinkedList<>();
start = System.currentTimeMillis();
for (int i = 1; i < 50000; i++) {
int x = random.nextInt(i);
list1.add(x, "a");
}
end = System.currentTimeMillis();
System.out.println("linkedList insert time " + (end - start));
}
只是插入5w数据,差距已经如此明显。
ArrayList拥有快速访问能力,不管是随机读还是顺序读,效率都高于LinkedList。
/**
* 随机读 array > linked
*/
@Test
public void test6() {
List<String> arr = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 200000; i++) {
arr.add("a");
}
List<String> linked = new LinkedList<>();
for (int i = 0; i < 200000; i++) {
linked.add("a");
}
long start = System.currentTimeMillis();
for (int i = 1; i < arr.size(); i++) {
int x = random.nextInt(i);
arr.get(x);
}
long end = System.currentTimeMillis();
System.out.println("arrayList insert time " + (end - start));
start = System.currentTimeMillis();
for (int i = 1; i < linked.size(); i++) {
int x = random.nextInt(i);
linked.get(i);
}
end = System.currentTimeMillis();
System.out.println("linkedList insert time " + (end - start));
}
/**
* 顺序删 array 》 linked
*/
@Test
public void test7() {
ArrayList<String> arr = new ArrayList<>();
for (int i = 0; i < 20000; i++) {
arr.add("a");
}
long start = System.currentTimeMillis();
for (int i = 0; i < arr.size(); i++) {
arr.remove(i);
}
long end = System.currentTimeMillis();
System.out.println("arrylist time:" + (end - start));
LinkedList<String> link = new LinkedList<>();
for (int i = 0; i < 20000; i++) {
link.add("a");
}
start = System.currentTimeMillis();
for (int i = 0; i < link.size(); i++) {
link.remove(i);
}
end = System.currentTimeMillis();
System.out.println("linkedlist time:" + (end - start));
}
标签:元素 插入数据 基本 sys alt 添加元素 复制 mil 增加
原文地址:https://www.cnblogs.com/le-le/p/12347303.html