jdk版本1.8,測試平臺mbp2016java
測試代碼node
package com.lly.springtest1.collection;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* @ClassName ICollection
* @Description TODO
* @Author lly
* @Date 2019/3/5 9:29 AM
* @Version 1.0
**/
@Slf4j
public class ICollection {
public static void test() {
LinkedList<String> links = new LinkedList<>();
int len = 6553631;
log.info(len + "");
long btime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
links.add("sss");
}
long etime = System.currentTimeMillis();
log.info("耗時:{},大小:{}", etime - btime, links.size());
long btime1 = System.currentTimeMillis();
ArrayList<String> arrays = new ArrayList<>();
for (int i = 0; i < len; i++) {
arrays.add("sss");
}
long etime1 = System.currentTimeMillis();
log.info("耗時:{},大小:{}", etime1 - btime1, arrays.size());
}
public static void main(String[] args) {
ICollection.test();
}
}
複製代碼
測試結果spring
package com.lly.springtest1.collection;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* @ClassName ICollection
* @Description TODO
* @Author lly
* @Date 2019/3/5 9:29 AM
* @Version 1.0
**/
@Slf4j
public class ICollection {
public static void test() {
LinkedList<String> links = new LinkedList<>();
int len = 100000;
log.info(len + "");
long btime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
links.addFirst("sss");
}
long etime = System.currentTimeMillis();
log.info("耗時:{},LinkedList大小:{}", etime - btime, links.size());
long btime1 = System.currentTimeMillis();
ArrayList<String> arrays = new ArrayList<>();
for (int i = 0; i < len; i++) {
arrays.add(0,"sss");
}
long etime1 = System.currentTimeMillis();
log.info("耗時:{},ArrayList大小:{}", etime1 - btime1, arrays.size());
}
public static void main(String[] args) {
ICollection.test();
}
}
複製代碼
package com.lly.springtest1.collection;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* @ClassName ICollection
* @Description TODO
* @Author lly
* @Date 2019/3/5 9:29 AM
* @Version 1.0
**/
@Slf4j
public class ICollection {
public static void test() {
LinkedList<String> links = new LinkedList<>();
int len = 10000;
log.info(len + "");
long btime = System.currentTimeMillis();
for (int i = 0; i < len; i++) {
links.add(links.size() / 2, "sss");
}
long etime = System.currentTimeMillis();
log.info("耗時:{},LinkedList大小:{}", etime - btime, links.size());
long btime1 = System.currentTimeMillis();
ArrayList<String> arrays = new ArrayList<>();
for (int i = 0; i < len; i++) {
arrays.add(arrays.size() / 2, "sss");
}
long etime1 = System.currentTimeMillis();
log.info("耗時:{},ArrayList大小:{}", etime1 - btime1, arrays.size());
}
public static void main(String[] args) {
ICollection.test();
}
}
複製代碼
數據量萬級別Linkedlist插入效率比ArrayList慢20倍 數組
下面讓我係統測試一下其餘數量級數據,而且加上隨機插入測試bash
public static void test(int listSize, int type) {
LinkedList<String> links = new LinkedList<>();
log.info("數組長度:{},插入方式{}", listSize, type);
long btime = System.currentTimeMillis();
for (int i = 0; i < listSize; i++) {
switch (type) {
case 0:
links.addFirst("測試數據");
break;
case 1:
links.add(links.size() / 2, "測試數據");
break;
case 2:
links.addLast("測試數據");
break;
default:
Random random = new Random();
int rd = random.nextInt(links.size()+1);
links.add(rd, "測試數據");
}
}
long etime = System.currentTimeMillis();
log.info("耗時:{}ms,LinkedList大小:{}", etime - btime, links.size());
long btime1 = System.currentTimeMillis();
ArrayList<String> arrays = new ArrayList<>();
for (int i = 0; i < listSize; i++) {
switch (type) {
case 0:
arrays.add(0, "測試數據");
break;
case 1:
arrays.add(arrays.size() / 2, "測試數據");
break;
case 2:
arrays.add("測試數據");
break;
default:
Random random = new Random();
int rd = random.nextInt(arrays.size()+1);
arrays.add(rd, "測試數據");
}
}
long etime1 = System.currentTimeMillis();
log.info("耗時:{}ms,ArrayList大小:{}", etime1 - btime1, arrays.size());
}
複製代碼
測試結果數據結構
在集合頭部插入實驗數據 dom
在集合中間插入實驗數據源碼分析
在集合尾部插入實驗數據 性能
在集合隨機位置插入數據學習
LinkedList源碼
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
複製代碼
ArrayList源碼
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
複製代碼
ArrayList:影響ArrayList性能的主要因素是擴容和數組複製,可是當size很大時數組擴容影響就會變小,那麼此時的效率就會提高,此時若是在中間部分插入數據時候,咱們要插入的位置爲i,數組長度是n,那麼就要變更i以後的n-i的數據。
LinkedList源碼
public void addFirst(E e) {
linkFirst(e);
}
private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
複製代碼
能夠看到LinkedList直接在頭部時候沒必要遍歷,因此效率很高,體現了LinkedList的插入效率高的特性
ArrayList源碼解釋同(指定位置插入)
LinkedList源碼
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
複製代碼
LinkedList:用傳入的值new一個Node對象,而後尾指針指向該新的Node
ArrayList源碼
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
複製代碼
ArrayList:若是超出容量須要擴容,不需擴容時直接數組元素賦值
結論:當數據量愈來愈大時,ArrayList比LinkedList快
緣由:當數據量大時,ArrayList每次擴容都能獲得很大的新空間,解決了前期頻繁擴容的劣勢,而LinkedList雖然有尾指針,可是每次add都要將對象new成一個Node(而ArrayList直接數組對應位置元素賦值)
數據量\插入位置 | 頭部 | 中間 | 尾部 | 隨機 |
---|---|---|---|---|
百 | 效率持平 | 效率持平 | 效率持平 | 效率持平 |
千 | LinkedList插入快 | 效率持平 | 效率持平 | ArrayList插入快 |
萬 | LinkedList插入快 | ArrayList插入快 | 效率持平 | ArrayList插入快 |
十萬 | LinkedList插入快 | ArrayList插入快 | ArrayList插入快 | ArrayList插入快 |
百萬 | LinkedList插入快 | ArrayList插入快 | ArrayList插入快 | ArrayList插入快 |