您的位置:首页 > 编程语言 > Java开发

JDK源码学习LinkedList

2014-06-24 23:16 302 查看
  LinkedList是List接口的子类,它底层数据结构是双向循环链表。LinkedList还实现了Deque接口(double-end-queue双端队列,线性collection,支持在两端插入和移除元素).所以LinkedList既可以被当作双向链表,还可以当做栈、队列或双端队列进行操作.文章目录如下:

  1.LinkedList的存储实现(jdk 1.7.0_51)

  2.LinkedList的读取实现

  3.LinkedList的性能分析

下面我们进入正题,开始学习LinkedList.

LinkedList的存储实现(jdk 1.7.0_51)

  我们知道LinkedList的底层数据结构是双向链表,也就是每个节点都持有指向前一个节点和指向后一个节点的指针.存储模型如下图:

   

public class LinkedListDemo {
public static void main(String[] args) {
LinkedList list = new LinkedList<Integer>();
for(int i=0;i<100000;++i){
list.add(i);
}

System.out.println("by index :"+printLinkedListByIndex(list)+" ms");
System.out.println("by Foreach :"+printLinkedListByForeach(list)+" ms");
System.out.println("by Iterator :"+printLinkedListByIterator(list)+" ms");
System.out.println("by RemoveFirst :"+printLinkedListByRemoveFirst(list)+" ms");
System.out.println("by RemoveLast :"+printLinkedListByRemoveLast(list)+" ms");
System.out.println("by PollFirst :"+printLinkedListByPollFirst(list)+" ms");
System.out.println("by PollLast:"+printLinkedListByPollLast(list)+" ms");

}

public static long printLinkedListByIndex(LinkedList list){
long startTime = System.currentTimeMillis();
for(int i=0;null!=list && i<list.size();++i){
list.get(i);
}
long endTime = System.currentTimeMillis();
return (endTime-startTime);
}

public static long printLinkedListByForeach(LinkedList<Integer> list){
long startTime = System.currentTimeMillis();
for(Integer i : list);
long endTime = System.currentTimeMillis();
return endTime-startTime;
}

public static long printLinkedListByIterator(LinkedList<Integer> list){
long startTime = System.currentTimeMillis();
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
iterator.next();
}
long endTime = System.currentTimeMillis();
return endTime-startTime;
}

public static long printLinkedListByRemoveFirst(LinkedList<Integer> list){
long startTime = System.currentTimeMillis();
for(int i =0;null!=list && i<list.size();++i){
list.removeFirst();
}
long endTime = System.currentTimeMillis();
return endTime-startTime;
}

public static long printLinkedListByRemoveLast(LinkedList<Integer> list){
long startTime = System.currentTimeMillis();
for(int i =0;null!=list && i<list.size();++i){
list.removeLast();
}
long endTime = System.currentTimeMillis();
return endTime-startTime;
}

public static long printLinkedListByPollFirst(LinkedList<Integer> list){
long startTime = System.currentTimeMillis();
for(int i =0;null!=list && i<list.size();++i){
list.pollFirst();
}
long endTime = System.currentTimeMillis();
return endTime-startTime;
}

public static long printLinkedListByPollLast(LinkedList<Integer> list){
long startTime = System.currentTimeMillis();
for(int i =0;null!=list && i<list.size();++i){
list.pollLast();
}
long endTime = System.currentTimeMillis();
return endTime-startTime;
}
}


View Code
运行结果:



  从运行结果可知:LinkedList遍历最高效的方式是移除header/tail元素,如果不要移除元素,则迭代器是最效率最高的方式,一定不能使用随机访问. 也尽量不要调用LinkedList中使用了随机访问方式操作的方法.

  曾经看过一篇讲LinkedList性能的文章,文章的作者觉得LinkedList有以下两个应用场景:

想实现一个FIFO队列缓冲区,并且很少在队列中间移除元素,因为 LinkedList能快速移除header和tail节点,所以用LinkedList是一个不错的选择。当然,更应该考虑使用ArrayDeque,因为ArrayDeque优化了header和tail元素的操作.

基本上不要在LinkedList中间添加或移除节点.因为在LinkedList中间操作节点,可能会需要随机访问LinkedList,LinkedList最大的弊端就在随机访问.

  该文的链接:http://java-performance.info/linkedlist-performance/,有兴趣的朋友可以看下.

ok,LinkedList的学习就先讲到这里了,欢迎大家一起交流,当然如果以后的工作和学习中学到了其他知识,随时会有更新.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: