开篇前言--LinkedList中的基本用法

在前面的博文中,小编介绍List接口中的ArrayList集合,List这个接口,有两个实现类,一个就是ArrayList另一个是LinkedList(链表),这两个类都实现了List接口,so。她们有很多相似的地方。LinkedList和ArrayList一样实现了List接口,但是她执行插入和删除操作时比ArrayList更加高效,因为她是基于链表的,但同时也决定了她在随机访问方面要比ArrayList弱一点。我们通过一系列的小demo来加深对LinkedList的了解。新建一个Class,取名为LinkedListTest1,编写code,addLast和addFirst方法,如下所示:

  1. package j2se.demo;
  2.  
  3. import java.util.LinkedList;
  4.  
  5. public class LinkedListTest1 {
  6. public static void main(String[] args) {
  7.  
  8. LinkedList list = new LinkedList();
  9. list.add("F");
  10. list.add("B");
  11. list.add("D");
  12. list.add("E");
  13. list.add("C");
  14.  
  15. list.addLast("Z");
  16. list.addFirst("A");
  17.  
  18. list.add(1,"A2");
  19.  
  20. System.out.println("最初的集合:"+list);
  21.  
  22. }
  23.  
  24. }

运行效果,如下图所示:

接着,我们来看一下remove的方法,编写相关代码,如下所示:

  1. package j2se.demo;
  2.  
  3. import java.util.LinkedList;
  4.  
  5. public class LinkedListTest1 {
  6. public static void main(String[] args) {
  7.  
  8. LinkedList list = new LinkedList();
  9. list.add("F");
  10. list.add("B");
  11. list.add("D");
  12. list.add("E");
  13. list.add("C");
  14.  
  15. list.addLast("Z");
  16. list.addFirst("A");
  17.  
  18. list.add(1,"A2");
  19.  
  20. System.out.println("最初的集合:"+list);
  21.  
  22. list.remove("F");
  23. list.remove(2);
  24.  
  25. System.out.println("变化后的集合:"+list);
  26.  
  27. }
  28.  
  29. }

运行效果如下所示:

接着,我们来看set方法,编写相关代码,如下所示:

  1. package j2se.demo;
  2.  
  3. import java.util.LinkedList;
  4.  
  5. public class LinkedListTest1 {
  6. public static void main(String[] args) {
  7.  
  8. LinkedList list = new LinkedList();
  9. list.add("F");
  10. list.add("B");
  11. list.add("D");
  12. list.add("E");
  13. list.add("C");
  14.  
  15. list.addLast("Z");
  16. list.addFirst("A");
  17.  
  18. list.add(1,"A2");
  19.  
  20. System.out.println("最初的集合:"+list);
  21.  
  22. list.remove("F");
  23. list.remove(2);
  24.  
  25. System.out.println("变化后的集合:"+list);
  26.  
  27. Object value = list.get(2);
  28. list.set(2, (String)value+"change");
  29. System.out.println("最后的集合:"+list);
  30.  
  31. }
  32.  
  33. }

运行效果,如下所示:

LinkedList底层实现--双向链表

我们知道LinkedList底层实现是一个链表,我们来看看什么是链表,首先我们来看线性结构,在数据结构中,一般将数据结构分为两大类,线性数据结构和非线性数据结构,其中线性数据结构有线性表、栈、队列、串、数组和文件;非线性数据结构有树和图。我们重点来看一下线性表的特征:

a、线性表的逻辑结构是n个数据元素的有限序列,如a1,a2,a3,...an,其中n为线性表的长度(n>=0),n=0的表称为空表;

b、在线性表中,数据元素呈线性关系,必存在唯一的称为“第一个”的数据元素;必存在唯一的称为“最后一个”的数据元素;除第一个元素外,每个元素都有且只有一个前驱元素;除最后一个元素外,每个元素都有且只有一个后继元素;

c、所有数据元素都在同一个线性表中必须是相同的数据类型;

d、线性表按其存储结构可以分为顺序表和链表,用顺序存储结构存储的线性表称为顺序表;用链式存储结构存储的线性表称为链表;

e、将线性表中的数据元素依次存放在某个存储区域中,所形成的表称为顺序表,一堆数组就是用顺序方式存储的线性表。

我们来看链表,对于一个顺序表来说,她存放这个元素本身就可以了,比如说3,我们存放这个3就可以了,因为她的地址是连续存放的,通过首地址就能一个一个找到后续元素的地址,但是对于链表来说,就不行,链表不是连续存放的。so,对于链表来说,光有数据还不够,必须还要有一个指向后继元素的引用才行。设计一个类,实现链表这个结构,该如何设计,应该包括哪些方法和属性呢?首先,我们需要设计一个node类,编写代码如下所示:

  1. package j2se.demo;
  2.  
  3. public class Node {
  4.  
  5. String data;//存放节点数据本身
  6. Node next;//存放指向下一个节点的引用
  7.  
  8. public Node(String data){
  9. this.data=data;
  10. }
  11.  
  12. }

这样,我们就定义好了Node这个类本身,接着,新建一个Class,取名为NodeTest,实现使得node1的后继是node2,node2的后继是node3;该怎么写呢?代码如下所示:

  1. package j2se.demo;
  2.  
  3. public class NodeTest {
  4.  
  5. public static void main(String[] args) {
  6.  
  7. Node node1 = new Node("node1");
  8. Node node2 = new Node("node2");
  9. Node node3 = new Node("node3");
  10.  
  11. node1.next=node2;
  12. node2.next=node3;
  13.  
  14. System.out.println(node1.next.next.data);
  15.  
  16. }
  17.  
  18. }

运行,如下所示:

接着,这个时候有一个node4,需要插入在node1和node2之间,编写相关代码部分,如下所示:

  1. package j2se.demo;
  2.  
  3. public class NodeTest {
  4.  
  5. public static void main(String[] args) {
  6.  
  7. Node node1 = new Node("node1");
  8. Node node2 = new Node("node2");
  9. Node node3 = new Node("node3");
  10.  
  11. node1.next=node2;
  12. node2.next=node3;
  13.  
  14. System.out.println(node1.next.next.data);
  15.  
  16. System.out.println("----------");
  17.  
  18. Node node4 = new Node("node4");
  19. node1.next=node4;
  20. node4.next=node2;
  21. System.out.println(node1.next.next.next.data);
  22.  
  23. }
  24.  
  25. }

运行,效果如下所示:

接着,我们将node4进行删除,代码如下所示:

  1. package j2se.demo;
  2.  
  3. public class NodeTest {
  4.  
  5. public static void main(String[] args) {
  6.  
  7. Node node1 = new Node("node1");
  8. Node node2 = new Node("node2");
  9. Node node3 = new Node("node3");
  10.  
  11. node1.next=node2;
  12. node2.next=node3;
  13.  
  14. System.out.println(node1.next.next.data);
  15.  
  16. System.out.println("----------");
  17.  
  18. Node node4 = new Node("node4");
  19. node1.next=node4;
  20. node4.next=node2;
  21. System.out.println(node1.next.next.next.data);
  22.  
  23. System.out.println("----------");
  24.  
  25. node1.next=node2;
  26. node4.next=null;
  27. System.out.println(node1.next.next.data);
  28.  
  29. }
  30.  
  31. }

运行效果如下所示:

接着,我们来看双向循环链表,使得node1的后一个元素是node2,node2的前一个元素是node1,node2的后一个元素是node3,node3的前一个元素是node2,node3的下一个元素是node1,node1的前一个元素是node3,首先我们需要定义一个Node2类,我们来看代码部分:

  1. package j2se.demo;
  2.  
  3. public class Node2 {
  4. Node2 previous;
  5. String data;
  6. Node2 next;
  7.  
  8. public Node2(String data){
  9. this.data=data;
  10. }
  11.  
  12. }

接着,我们来实现,代码如下所示:

  1. package j2se.demo;
  2.  
  3. public class NodeTest2 {
  4. public static void main(String[] args) {
  5. Node2 node1 = new Node2("data1");
  6. Node2 node2 = new Node2("data2");
  7. Node2 node3 = new Node2("data3");
  8.  
  9. node1.next = node2;
  10. node2.next = node3;
  11. node3.next = node1;
  12.  
  13. node3.previous = node2;
  14. node2.previous = node1;
  15. node1.previous = node3;
  16.  
  17. System.out.println(node1.next.next.data);
  18. System.out.println(node3.previous.previous.data);
  19.  
  20. }
  21.  
  22. }

运行效果,如下所示:

接着,小伙伴可以对其进行插入和删除的操作,和单向链表大同小异,小伙伴们可以自己动手实现。小编为什么要讲链表呢?因为LinkedList的底层实现就是一个双向链表,这个如果明白了,LinkedList的源码也就明白了,跟进去LinkedList的源码,我们来看她的部分源码,我们首先来看LinkedList类结构的定义,如下所示:

  1. //通过LinkedList实现的接口可知,其支持队列操作,双向列表操作,能被克隆,支持序列化
  2. public class LinkedList<E>
  3. extends AbstractSequentialList<E>
  4. implements List<E>, Deque<E>, Cloneable, java.io.Serializable
  5. {
  6. // LinkedList的大小(指其所含的元素个数)
  7. transient int size = 0;
  8.  
  9. /**
  10. * 指向第一个节点
  11. * 不变的: (first == null && last == null) ||
  12. * (first.prev == null && first.item != null)
  13. */
  14. transient Node<E> first;
  15.  
  16. /**
  17. * 指向最后一个节点
  18. * 不变的: (first == null && last == null) ||
  19. * (last.next == null && last.item != null)
  20. */
  21. transient Node<E> last;
  22.  
  23. ......
  24. }

通过上面的代码,我们知道,
a、LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
b、LinkedList 实现 List 接口,能对它进行队列操作。
c、LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
d、LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
e、LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
f、LinkedList 是非同步的。
LinkedList包含了三个重要的对象:first、last 和 size。
a、 first 是双向链表的表头,它是双向链表节点所对应的类Node的实例
b、 last 是双向链表的最后一个元素,它是双向链表节点所对应的类Node的实例
c、 size 是双向链表中节点的个数。
接着我们来看一下LinkedList的构造函数,如下所示:

  1. //构建一个空列表
  2. public LinkedList() {
  3. }
  4.  
  5. /**
  6. * 构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回的顺序排列的
  7. * @param c 包含用于去构造LinkedList的元素的collection
  8. * @throws NullPointerException 如果指定的collection为空
  9. */
  10. //构建一个包含指定集合c的列表
  11. public LinkedList(Collection<? extends E> c) {
  12. this();
  13. addAll(c);
  14. }

LinkedList的源码部分就先介绍到这里,小伙伴可以自己点进去看看哦,List的实现接口,小编已经介绍完两个了,一个ArrayList和LinkedList,既然她们两个都是实现了List接口,那么她们有什么样的区别和联系呢?

ArrayList && LinkedList 比较

a、ArrayList是基于数组,LinkedList基于链表实现。
b、对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。
c、对于新增和删除操作add和remove,LinedList比较占优势,因为ArrayList要移动数据。
d、查找操作indexOf,lastIndexOf,contains等,两者差不多。
小编寄语:该博文,小编主要介绍了list接口中另一个实现类LinkedList,从LinkedList的基本方法,到LinkedList的源码部分,和ArrayList进行对比,ArrayList底层采用数组实现,LinkedList采用双向链表实现,当执行插入或者删除操作的时候,采用LinkedList比较好;当执行搜索操作的时候,采用ArrayList比较好。小伙伴在学习的过程中,可以多查一查API文档,一起加油,小伙伴们`(*∩_∩*)′。

【java集合系列】--- LinkedList的更多相关文章

  1. Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例

    概要  前面,我们已经学习了ArrayList,并了解了fail-fast机制.这一章我们接着学习List的实现类——LinkedList.和学习ArrayList一样,接下来呢,我们先对Linked ...

  2. Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

    概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Ja ...

  3. Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  4. Java 集合系列 04 LinkedList详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  5. java集合系列之LinkedList源码分析

    java集合系列之LinkedList源码分析 LinkedList数据结构简介 LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含 ...

  6. 【转】Java 集合系列08之 List总结(LinkedList, ArrayList等使用场景和性能分析)

    概要 前面,我们学完了List的全部内容(ArrayList, LinkedList, Vector, Stack). Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例 Ja ...

  7. Java 集合系列04之 fail-fast总结(通过ArrayList来说明fail-fast的原理、解决办法)

    概要 前面,我们已经学习了ArrayList.接下来,我们以ArrayList为例,对Iterator的fail-fast机制进行了解.内容包括::1 fail-fast简介2 fail-fast示例 ...

  8. Java 集合系列目录(Category)

    下面是最近总结的Java集合(JDK1.6.0_45)相关文章的目录. 01. Java 集合系列01之 总体框架 02. Java 集合系列02之 Collection架构 03. Java 集合系 ...

  9. Java 集合系列07之 Stack详细介绍(源码解析)和使用示例

    概要 学完Vector了之后,接下来我们开始学习Stack.Stack很简单,它继承于Vector.学习方式还是和之前一样,先对Stack有个整体认识,然后再学习它的源码:最后再通过实例来学会使用它. ...

  10. Java 集合系列 09 HashMap详细介绍(源码解析)和使用示例

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

随机推荐

  1. linux内核源码分析 - nvme设备的初始化

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 本文基于3.18.3内核的分析,nvme设备为pcie接口的ssd,其驱动名称为nvme.ko,驱动代码在dri ...

  2. 对于python这门课程的一些想法、计划、期望

    本人是一名大二的码农,专业信息安全.之前在知乎上看到过对于python一些评论,说用python写的代码和诗一样.也在网上大概的了解了一下,python要求有严格的缩进.学习python语言,最想学的 ...

  3. rocketmq番外篇(一):开发命令行

    匠心零度 转载请注明原创出处,谢谢! 说在前面 虽然是以rocketmq引出的开发命令行,但是任何java应用如果需要都可以借鉴引用,也是通用技术. 主题 rocketmq使用例子 Apache Co ...

  4. Jenkins配置Gogs webhook插件

    前言 我们在前面使用Jenkins集合Gogs来进行持续集成的时候,选择的是Jenkins定时检测git仓库是否有更新来决定是否构建.也就是说,我们提交了代码Jenkins并不会马上知道,那么我们可以 ...

  5. JS刷票神器

    var all = document.querySelectorAll('td[width="80"]'); setInterval(function(){ document.ge ...

  6. Android重构篇——项目架构篇

    版权声明:本文为博主原创文章,未经博主允许不得转载. 转载请表明出处:http://www.cnblogs.com/cavalier-/p/6823777.html 前言 大家好,我是Cavalier ...

  7. [Codeforces 863D]Yet Another Array Queries Problem

    Description You are given an array a of size n, and q queries to it. There are queries of two types: ...

  8. [HNOI 2001]求正整数

    Description 对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m.例如:n=4,则m=6,因为6有4个不同整数因子1,2,3,6:而且是最小的有4个因子的整数. Input n ...

  9. ●BZOJ 2588 Spoj 10628. Count on a tree

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...

  10. 2015 多校联赛 ——HDU5410(dp)

    Sample Input 1 100 2 10 2 1 20 1 1   Sample Output 21 题意:共有m元钱和n种东西,求每种单价p,而且你买x个该种物品可以得到Ax+B个,求m元钱最 ...