关于ArrayList和LinkedList的简单测试
首先简单说说ArrayList和LinkedList的特点:
☆ ArrayList的底层数据结构是一个数组,但是它区别于普通一维数组不同的点在于,普通的一维数组在声明的时候长度是固定的,但是ArrayList是一个动态的,长度可变的数组,它在声明的时候不需要声明长度,而且ArrayList集合中可以添加任何类型的数据,并且添加的数据都会转换成Object类型,而在普通的数组中只能添加同一种数据类型的数据
☆ LinkedList的底层数据结构是链表形式的,它同样**允许元素值是任何数据,包括null,**链表式的数据结构是在于链表里面的数据不同于数组在内存地址中连续的空间,链表中的数据并不是存在于一个连续的内存地址中,链表里数据元素的逻辑顺序是通过链表中的引用次序实现的,每个链表中的数据元素都保存着自己或前或后或前后的数据引用地址.
☆ 今天主要对比一下ArrayList和LinkedList在内存中储存数据和插入数据的速度.
首先对比分别在两个集合中插入500万个数字的速度
ArrayList arr = new ArrayList();
long start = System.currentTimeMillis();
for (int i = 0; i < 5000000; i++) {
arr.add(i);
}
long spend = System.currentTimeMillis()-start;
System.out.println("往ArrayList新增500万个数字的时间spend="+spend);
LinkedList link = new LinkedList();
long start1 = System.currentTimeMillis();
for (int i = 0; i < 5000000; i++) {
link.add(i);
}
long spend1 = System.currentTimeMillis()-start1;
System.out.println("在LinkedList中添加500万个数字的时间spend1="+spend1);
然后看看运行结果
*******************ArrayList测试********************
往ArrayList新增500万个数字的时间spend=161ms
*******************LinkedList测试********************
在LinkedList中添加500万个数字的时间spend1=258ms
第二步对比ArrayList和LinkedList在头部中部和尾部插入数据的速度
首先是ArrayList的插入代码
start = System.currentTimeMillis();
arr.add(0,1234567);
spend = System.currentTimeMillis()-start;
System.out.println("ArrayList在头部添加数据的spend="+spend);
start = System.currentTimeMillis();
arr.add(2200000,76543291);
spend = System.currentTimeMillis()-start;
System.out.println("ArrayList在中部添加数据的spend="+spend);
start = System.currentTimeMillis();
arr.add(7654321);
spend = System.currentTimeMillis()-start;
System.out.println("ArrayList在尾部添加数据的spend="+spend);
然后是LinkedList的插入代码
start1 = System.currentTimeMillis();
link.addFirst(1234567);
spend1 = System.currentTimeMillis()-start1;
System.out.println("LinkedList在头部添加数据的spend1="+spend1);
start1 = System.currentTimeMillis();
link.add(2200000,7654321);
spend1 = System.currentTimeMillis()-start1;
System.out.println("LinkedList在中部添加数据的spend1="+spend1);
start1 = System.currentTimeMillis();
link.addLast(7654321);
spend1 = System.currentTimeMillis()-start1;
System.out.println("LinkedList在尾部添加数据的spend1="+spend1);
对比一下结果
ArrayList在头部添加数据的spend=4ms
ArrayList在中部添加数据的spend=3ms
ArrayList在尾部添加数据的spend=0ms
LinkedList在头部添加数据的spend1=0ms
LinkedList在中部添加数据的spend1=18ms
LinkedList在尾部添加数据的spend1=0ms
第三步对比ArrayList和LinkedList在头部中部和尾部读取数据的速度
首先是ArrayList的读取代码
start = System.currentTimeMillis();
int num = (int)arr.get(0);
System.out.println("ArrayList中第1个数据是"+num);
spend = System.currentTimeMillis()-start;
System.out.println("ArrayList中得到第1个数据的时间spend="+spend);
start = System.currentTimeMillis();
num = (int)arr.get(2222222);
System.out.println("ArrayList中第2222222个数据是"+num);
spend = System.currentTimeMillis()-start;
System.out.println("ArrayList中得到第2222222个数据的时间spend="+spend);
start = System.currentTimeMillis();
num = (int)arr.get(4999999);
System.out.println("ArrayList中最后1个数据是"+num);
spend = System.currentTimeMillis()-start;
System.out.println("ArrayList中得到最后1个数据的时间spend="+spend);
然后是LinkedList的读取代码
start1 = System.currentTimeMillis();
int num1 = (int)link.getFirst();
System.out.println("LinkedList中第1个数据是"+num1);
spend1 = System.currentTimeMillis()-start1;
System.out.println("LinkedList得到头部的数据花费的时间spend1="+spend1);
start1 = System.currentTimeMillis();
num1 = (int)link.get(2222222);
System.out.println("LinkedList中第2222222个数据是"+num1);
spend1 = System.currentTimeMillis()-start1;
System.out.println("LinkedList得到中间的数据花费的时间spend1="+spend1);
start1 = System.currentTimeMillis();
num1 = (int)link.getLast();
System.out.println("LinkedList中最后1个数据是"+num1);
spend1 = System.currentTimeMillis()-start1;
System.out.println("LinkedList得到尾部的数据花费的时间spend1="+spend1);
最终运行结果
ArrayList中第1个数据是1234567
ArrayList中得到第1个数据的时间spend=0ms
ArrayList中第2222222个数据是2222220
ArrayList中得到第2222222个数据的时间spend=0ms
ArrayList中最后1个数据是4999997
ArrayList中得到最后1个数据的时间spend=1ms
LinkedList中第1个数据是1234567
LinkedList得到头部的数据花费的时间spend1=0ms
LinkedList中第2222222个数据是2222220
LinkedList得到中间的数据花费的时间spend1=17ms
LinkedList中最后1个数据是7654321
LinkedList得到尾部的数据花费的时间spend1=0ms
通过这三个测试可以得到这样一个结果:
■ ArrayList集合可以通过索引来获取元素,所以在随机读取数据的时候的有很大优势,花费的时间最少,效率最高,但是如果在头部插入数据时,所有数据都要在内存中移动一位,所以会增加花费的时间,在频繁在不是尾部的位置插入数据时,会造成效率的低下.
■ LinkeList集合在,插入头部和尾部数据的时候和读取头部和尾部信息的时候基本是零损耗,因为它不用移动集合中其他元素的位置,虚拟机只要找到保留头部和尾部信息的两个数据元素就可以进行插入和读取,但是如果在中部进行插入和读取时,则需要花费比较多的时间,因为链表里数据元素的逻辑顺序是通过链表中的引用次序实现的,所以要理清楚顺序是比较花费时间的.
整体对比下来的结论
① ArrayList和LinkedList如果一直在尾部存入数据时,ArrayList会更胜一筹
② 如果在头部存入数据时,LinkedList基本是零损耗,会更加适用
③ 在随机读取时,ArrayList的优势比较明显,无论是头部,中部,尾部读取时的速度都很快,但是LinkeList的读取头部和尾部的数据时比较快,对于中部数据读取则会稍慢一些
所以,最终我这样认为,
❶ 在随机读取需求比较大的应用场景下,无疑是选择ArrayList是最好的
❷ 如果在随机读取需求比较小,而且频繁插入和删除数据在头部居多的应用场景中LinkedList会更加合适
❸ 但是如果插入和删除数据都在非头部的位置时,LinkedList和ArrayList差别不大,都可以选择.
以上就是个人对ArrayList和LinkedList的区别的一点点个人看法,以后有更深入的使用体验后再行修改