一、简介

LinkedList与ArrayList一样都实现了List接口,不过LinkedList底层实现是双向链表,对于插入、修改、删除速度比较快,对于查询就比较慢,因为要循环遍历查找。本章将模仿LinkedList源码实现一个简单的自定义LinkedList,以帮助饿哦们理解LinkedList底层是怎么实现的。

二、实现原理

LinkedList底层是通过双向链表实现的,通过一系列的节点Node串成一条链结构,一般操作思想就是找到索引对应的元素,找到前一节点previous和后一节点next,然后使其串起来一条链结构。

三、自定义LinkedList

package wsh.linkedlist;/*** 节点类** @author weishihuai* @date 2018/9/26 21:14*/
public class Node {/*** 前一个节点*/private Node previous;/*** 下一个节点*/private Node next;/*** 当前节点的值*/private Object object;public Node() {}public Node(Node previous, Node next, Object object) {this.previous = previous;this.next = next;this.object = object;}public Node getPrevious() {return previous;}public void setPrevious(Node previous) {this.previous = previous;}public Node getNext() {return next;}public void setNext(Node next) {this.next = next;}public Object getObject() {return object;}public void setObject(Object object) {this.object = object;}
}
package wsh.linkedlist;/*** 自定义LinkedList,帮助理解底层实现** @author weishihuai* @date 2018/9/26 21:14* <p>* 说明:* 1. LinkedList底层实现是双向链表,插入、修改、删除快,查询慢* 2. 基本操作的思想: 找到索引对应的元素,找到前一节点和后一节点,然后串起来一条链。*/
public class CustomLinkedList {/*** 第一个节点*/private Node first;/*** 最后一个节点*/private Node last;/*** 链表长度*/private int size;/*** 新增一个元素** @param object 对象*/public void add(Object object) {//如果第一个节点为空,说明为空链表if (null == first) {//创建一个新节点,赋值给first、lastNode node = new Node();node.setPrevious(null);node.setNext(null);node.setObject(object);//新创建的节点既是第一个节点,也是最后一个节点first = node;last = node;} else {//直接在last后面添加一个新的节点Node node = new Node();node.setPrevious(last);node.setObject(object);node.setNext(null);//串成一条链last.setNext(node);//新创建的节点变成最后一个节点last = node;}//每新增一个节点,长度需要加1size++;}/*** 获取LinkedList的长度** @return LinkedList的长度*/public int size() {return size;}/*** 获取指定位置的元素* 原理: 从第一个节点开始,循环遍历节点,temp = temp.getNext()** @param index 索引* @return 元素的值*/public Object get(int index) {//判断索引是否越界if (index < 0 || index >= size) {throw new IllegalArgumentException("下标越界.....");}Node temp = null;if (null != first) {//0 1 2 3 4 5temp = first;for (int i = 0; i < index; i++) {temp = temp.getNext();}}return null != temp ? temp.getObject() : null;}/*** 删除指定索引的元素* 原理: 找到指定下标所对应的元素,找出该节点对应的上一个节点和下一个节点,把上一个节点的next指向下一个节点,下一个节点的previous指向上一个节点,这样就跳过了该节点,达到 删除的效果。** @param index 索引*/public void remove(int index) {//判断索引是否越界if (index < 0 || index >= size) {throw new IllegalArgumentException("下标越界.....");}Node temp = null;if (null != first) {//0 1 2 3 4 5temp = first;for (int i = 0; i < index; i++) {temp = temp.getNext();}}if (null != temp) {Node previous = temp.getPrevious();Node next = temp.getNext();previous.setNext(next);if (null != next) {next.setPrevious(previous);}size--;}}/*** 指定位置插入对象* 原理: 找到指定位置的元素,接着找到该节点对应的上一个节点,新建一个节点,用于连接之前的前后节点的桥梁** @param index  索引* @param object 对象*/public void add(int index, Object object) {//判断索引是否越界if (index < 0 || index >= size) {throw new IllegalArgumentException("下标越界.....");}Node temp = null;if (null != first) {//0 1 2 3 4 5temp = first;for (int i = 0; i < index; i++) {temp = temp.getNext();}}Node newNode = new Node();newNode.setObject(object);if (null != temp) {Node previous = temp.getPrevious();previous.setNext(newNode);newNode.setPrevious(previous);newNode.setNext(temp);temp.setPrevious(newNode);size++;}}public Node getFirst() {return first;}public void setFirst(Node first) {this.first = first;}public Node getLast() {return last;}public void setLast(Node last) {this.last = last;}public int getSize() {return size;}public void setSize(int size) {this.size = size;}
}

四、部分方法详解

【a】Node节点类

1. 节点类主要包含上一节点、下一节点以及当前节点的值

/*** 前一个节点*/private Node previous;/*** 下一个节点*/private Node next;/*** 当前节点的值*/private Object object;

【b】add(Object object) {}      往链表中插入元素

1. 实现原理:

a. 如果第一个节点为空,说明是一个空链表,那么需要创建一个新的节点,这个节点既是首节点,也是尾节点,

b. 如果第一个节点不为空,说明链表已经存在元素,那么只需要在当前last最后一个元素后面插入新创建的节点,并且把当前最后一个节点指定为新创建的节点(最新插入的节点变成最后一个节点)。

2. 注意每新插入一个元素,list的长度需要加1。

【c】get(int index) {}    获取指定索引对应的元素的值

1. 实现原理: 循环index次,定义一个临时变量temp,第一次从首节点开始查找,循环index次,执行temp = temp.getNext()

即循环将下一个节点赋值给temp,直到循环结束,就会找到相应的元素,返回其值。如果没找到返回null。

2. 注意需要判断索引是否合法。

【d】remove(int index) {}    删除指定索引的元素

1. 实现原理: 找到指定下标所对应的元素,找出该节点对应的上一个节点和下一个节点,把上一个节点的next指向下一个节点,下一个节点的previous指向上一个节点,这样就跳过了该节点,达到 删除的效果。

2. 注意需要判断索引是否合法

【e】add(int index, Object object) {}         往指定位置插入相应的元素

1. 实现原理: 找到指定位置的元素,接着找到该节点对应的上一个节点,新建一个节点,用于连接之前的前后节点的桥梁.

2. 注意需要判断索引是否合法

五、测试

package wsh.linkedlist;/*** 测试** @author weishihuai* @date 2018/9/26 21:19*/
public class TestCustomLinkedList {public static void main(String[] args) {CustomLinkedList customLinkedList = new CustomLinkedList();/***********************************add(object)***************************************/customLinkedList.add("aaa");customLinkedList.add("bbb");customLinkedList.add("ccc");/***********************************size()********************************************///3System.out.println(customLinkedList.size());/***********************************get(index)****************************************///bbbSystem.out.println(customLinkedList.get(1));//越界: java.lang.NullPointerException//System.out.println(customLinkedList.get(3));/***********************************remove(index)*************************************///3System.out.println(customLinkedList.size());customLinkedList.remove(2);//2System.out.println(customLinkedList.size());/***********************************add(index,object)********************************/customLinkedList.add(1, "ddd");for (int i = 0; i < customLinkedList.size(); i++) {//aaa ddd bbbSystem.out.println(customLinkedList.get(i));}}}

六、总结

以上就是关于LinkedList底层实现的一些基础原理,当然很多细节没考虑到,主要是能够帮助我们理解LinkedList底层是通过操作链表结构来实现数据的操作,简单理解就是找到索引对应的元素,然后找到上一节点以及下一节点,思想就是怎么把这些节点串成一条链结构,可以结合画图来理解一下。本文是作者的一些总结以及方法,仅供大家参考学习,一起学习一起进步。

Java集合Collection之实现原理解读(LinkedList)相关推荐

  1. Java集合Collection接口中的常用方法演示

    Java集合Collection接口中的常用方法演示 添加 add(Objec tobj) 和 addAll(Collection coll) 获取有效元素的个数 int size() 清空集合 vo ...

  2. 考考基础部分,谈谈Java集合中HashSet的原理及常用方法

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者:工匠初心 cnblogs.com/LiaHon/p/1125 ...

  3. Java 集合系列(4): LinkedList源码深入解析1

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 前面,我们已经学习了ArrayList,并了解了fail-fast ...

  4. Java集合Collection与List的关系、常见用法

    关系树 [java] view plain copy print? ---|Collection: 单列集合 ---|List: 有存储顺序, 可重复 ---|ArrayList: 数组实现, 查找快 ...

  5. Java集合Collection源码系列-ArrayList源码分析

    Java集合系列-ArrayList源码分析 文章目录 Java集合系列-ArrayList源码分析 前言 一.为什么想去分析ArrayList源码? 二.源码分析 1.宏观上分析List 2.方法汇 ...

  6. java集合Collection常用方法详解

    前言 出去面试的时候,对java的集合框架考察的知识点还是蛮多的.除了基础的集合常见API使用,对集合底层的实现原理以及数据结构等也有很多考察方面.而自己对这方面知之甚少,特地抽空进行研究和学习一下. ...

  7. Java 集合Collection常见知识点汇总~

    看了一些所谓大公司的JAVA面试问题,发现对于JAVA集合类的使用都比较看重似的,而自己在这方面还真的是所真甚少,抽空也学习学习吧. java.util包中包含了一系列重要的集合类,而对于集合类,主要 ...

  8. Java集合 Collection

    Jdk提供了一些特殊的类,用来保存数量不确定的对象,存储任意类型对象,长度可变.这些类统称为集合. 集合类位于Java.util包中,按存储结构分为Collection单列集合和Map双列集合. Co ...

  9. 略解java集合Collection

    java集合 一.什么是集合 集合是指具有某种特定性质的具体的或抽象的对象汇总而成的集体 而java面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,Java就提供了集合类 二. ...

  10. java 先进先出的map_「 深入浅出 」java集合Collection和Map

    本系列文章主要对java集合的框架进行一个深入浅出的介绍,使大家对java集合有个深入的理解. 本篇文章主要具体介绍了Collection接口,Map接口以及Collection接口的三个子接口Set ...

最新文章

  1. iview 表单 验证_iview必备技能一、表单验证规则
  2. 如何用Matlab求矩阵的秩、乘积、逆、行列式的值、转置
  3. android 真机 sqlite3,在android真机上使用sqlite3
  4. 我的世界服务器linux加mod,在Linux下搭建带MOD 我的世界(Minecraft)服务器
  5. [C++] c language 23 keywords
  6. lane是什么意思_什么是Trunk?Trunk详解
  7. 《Cocos2D-x权威指南》——第3章 Cocos2D-x中的核心类
  8. u3d商业级开心消消乐源码开发总结
  9. PR快节奏短视频转场预设 时尚新款照片展示PR免费转场预设
  10. MateMask连接本地私有链节点ganache
  11. 女孩们,请别到职场卖萌,甘当不专…
  12. 阿里云ECS云服务器实例重置-更换操作系统
  13. 如何将一个vector内容赋值给另一个vector C/C++
  14. Mac下的Adobe卸载后无法重装
  15. 明明没PS,看起来却像PS过的32张照片
  16. 51单片机教程:8*8 点阵显示字符、数字、简单汉字
  17. 清空Github仓库方法
  18. springboot + Vue 整合阿里云视频点播 | Spring Boot 20
  19. 浅谈PageRank
  20. Java 实现 WORD转PDF,用Documents4j

热门文章

  1. C/C++[codeup 1962]单词替换
  2. Java 最长递增子序列_最长递增子序列问题 Java
  3. OpenVINO DL workbench的docker安装
  4. 利用数组构造MaxTree
  5. python快速编程入门课本中的名片管理器_Python-名片管理器
  6. 线性代数第八章 λ 矩阵 定理8 多项式最大公约数的性质
  7. (详细带你分析错误):No property 属性名 found for type 类名,总结了其他解决办法
  8. android多地图切换,Android的谷歌地图卫星切换
  9. selenium-绕过登录
  10. 利用maven命令将外部jar包导进maven仓库