写完第一篇笔记后又翻了好多博客,觉得这篇对LinkedList的理解有帮助,链接如下:
直接上博主结论:
ArrayList是数组的实现形式(内部存储结构是一个数组):
添加新的元素到数组末尾时,如果超过了当前容量,就要对数组进行扩容,扩充为原来大小的1.5倍,由于扩容牵涉到整个数组的copy,对性能影响较大,所以如果知道要存放容量的大小,尽量在创建ArrayList时指定
ArrayList就是一个数组实现,适用于, 查找操作较多,而修改操作(add和delete)较少的情况,由于实现较为简单。
LinkedList适用于:查找较少,修改较多的情况(这与LinkedList的链式结构是有关系的)。
LinkedList是链表结构的实现形式(内部存储结构是一个链表形式)。
另外,由于LinkedList实现了双向队列Deque接口,所以也具有队列的相关操作,可以当做一个队列使用。
本篇博客着重分析了linkedList的增删改差的一些源码,可以让你对linkedList有更深刻的认知(如果平时使用不多的话),源码就不重复展示了。
关于RandomAccess
在小记【1】里提到了这个接口,我也找了相关博客:
简单说RandomAccess接口是影响你遍历算法的,没有实现RandomAccess的,和实现了RandomAccess的集合,走增强for循环遍历时的算法是不一样的。
官方是推荐我们去让集合实现这个接口,但linkedList并没有实现它,而是实现了队列接口
博客还提供了测试代码:
<span style="font-size: small;">/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package testrandomaccess;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess;
/**
*
* @author bolong
*/
public class TestRandomAccess {
// 初始化列表
public static void initList(List list, int n) {
for (int i = 0; i < n; i++) {
list.add(i);
}
}
//使用循环进行对列表的迭代
public static void traverseWithLoop(List list) {
long starttime = 0;
long endtime = 0;
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
}
endtime = System.currentTimeMillis();
System.out.println("使用loop迭代一共花了" + (endtime - starttime) + "ms时间");
}
//使用迭代器对列表进行迭代
public static void traverseWithIterator(List list) {
long starttime = 0;
long endtime = 0;
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (Iterator itr = list.iterator(); itr.hasNext();) {
itr.next();
}
}
endtime = System.currentTimeMillis();
System.out.println("使用Iterator迭代一共花了" + (endtime - starttime) + "ms时间");
}
public static void traverse(List list) {
long starttime = 0;
long endtime = 0;
if (list instanceof RandomAccess) {
System.out.println("该list实现了RandomAccess接口");
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
}
endtime = System.currentTimeMillis();
System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");
} else {
System.out.println("该list未实现RandomAccess接口");
starttime = System.currentTimeMillis();
for (int count = 0; count <= 1000; count++) {
for (Iterator itr = list.iterator(); itr.hasNext();) {
itr.next();
}
}
endtime = System.currentTimeMillis();
System.out.println("迭代一共花了" + (endtime - starttime) + "ms时间");
}
}
public static void main(String[] args) {
ArrayList arraylist = new ArrayList();
LinkedList linkedlist = new LinkedList();
initList(arraylist, 1000);
initList(linkedlist, 1000);
traverse(arraylist);
traverse(linkedlist);
traverseWithIterator(arraylist);
traverseWithLoop(arraylist);
traverseWithIterator(linkedlist);
traverseWithLoop(linkedlist);
}
}
</span>
结论:
根据程序输出的结果的确证明了,arraylist等实现了RandomAccessj接口的类在进行迭代时使用loop效率更高,而linkedList那些未实现该接口的类在进行迭代时使用Iterator进行迭代效率更高.