自己根据java的LinkedList源码编写的一个简单的LinkedList实现
自己实现了一个简单的LinkedList
/**
* Create by andy on 2018-07-03 11:44
* 根据 {@link java.util.LinkedList}源码 写了一个简单的实现,方便理解设计流程
* 该类是线程不安全的
*/
public class FrameLinkedList<E> {
private Node<E> first;
private Node<E> last;
private int size;
public int getSize() {
return size;
}
public E getFirst() {
if (first == null)
return null;
return first.item;
}
public E getLast() {
if (last == null)
return null;
return last.item;
}
/**
* 根据元素位置取元素的值
* 从这个例子中就可以看出来,为什么LinkedList获取元素比较慢,因为每次取出元素都有进行一次循环!!!!
*
* @param index
* @return
*/
public E get(int index) {
if (index < 0)
throw new IllegalArgumentException("参数不能小于0");
if (index >= size)
throw new IllegalArgumentException("参数太大了,当前集合最大长度为:" + size);
//如果索引小于当前元素个数的一半,就从头部开始循环,否则从尾部开始循环
Node<E> node = first;
if (index < size >> 1) {
//把头给节点,便于下面递归循环
for (int i = 0; i < index; i++) {
node = node.next;
}
} else {
//把尾给节点,便于下面递归循环
node = last;
for (int i = size - 1; i > index; i--) {
node = node.prev;
}
}
return node.item;
}
public void add(E e) {
if (size == 0) {
//第一次添加对象
Node<E> curr = new Node<>(e, null, null);
curr.item = e; //当前对象
first = curr;
last = curr;
} else {
Node<E> curr = new Node<>(e, last, null);
last.next = curr;
last = curr;
}
size++;
}
public boolean remove(E e) {
if (size == 0) return false;
//分两种来处理防止e为null的时候出现空指针异常
if (e == null) {
for (Node<E> n = first; n != null; n = n.next) {
if (n.item == null) {
remove(n);
return true;
}
}
} else {
for (Node<E> n = first; n != null; n = n.next) {
if (e.equals(n.item)) {
remove(n);
return true;
}
}
}
return false;
}
private void remove(Node<E> node) {
Node<E> prev = node.prev;
Node<E> next = node.next;
if (prev == null) {
//移除的是第一个
node.next = null;
next.prev = null;
first = next;
} else if (next == null) {
//移除的是最后一个
node.prev = null;
prev.next = null;
last = prev;
} else {
//移除的是中间
node.prev = null;
node.next = null;
prev.next = next;
next.prev = prev;
}
node.item = null; //便于回收item
size--;
}
private static class Node<E> {
E item; //当前对象
Node<E> prev; //上一个对象的Node
Node<E> next; //下一个对象的Node
Node(E item, Node<E> prev, Node<E> next) {
this.item = item;
this.prev = prev;
this.next = next;
}
}
public static void main(String[] args) {
FrameLinkedList<String> list = new FrameLinkedList<>();
list.add("a1");
list.add("a2");
list.add("a3");
list.add("a4");
list.add("a5");
for (int i = 0; i < list.getSize(); i++) {
System.out.println(list.get(i));
}
System.out.println("-------");
list.remove(list.get(4));
for (int i = 0; i < list.getSize(); i++) {
System.out.println(list.get(i));
}
}
}
自己根据java的LinkedList源码编写的一个简单的LinkedList实现的更多相关文章
- Flink源码分析 - 剖析一个简单的Flink程序
本篇文章首发于头条号Flink程序是如何执行的?通过源码来剖析一个简单的Flink程序,欢迎关注头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech) ...
- Java-链表LinkedList源码原理分析,并且通过LinkedList构建队列
在这里我们介绍一下最简单的链表LinkedList: 看一下add()方法: public boolean add(E e) { linkLast(e); return true; } void li ...
- 转:【Java集合源码剖析】LinkedList源码剖析
转载请注明出处:http://blog.csdn.net/ns_code/article/details/35787253 您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票 ...
- java基础解析系列(十)---ArrayList和LinkedList源码及使用分析
java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...
- 【java集合框架源码剖析系列】java源码剖析之LinkedList
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 在实际项目中LinkedList也是使用频率非常高的一种集合,本博客将从源码角度带领大家学习关于LinkedList的知识. ...
- Java集合:LinkedList源码解析
Java集合---LinkedList源码解析 一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...
- Java集合之LinkedList源码解析
LinkedList简介 LinkedList基于双向链表,即FIFO(先进先出)和FILO(先进后出)都是支持的,这样它可以作为堆栈,队列使用 继承AbstractSequentialList,该类 ...
- Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap
声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...
- 【源码阅读】Java集合之二 - LinkedList源码深度解读
Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章; 本文是第二篇LinkedList. ---@pdai JDK版 ...
随机推荐
- 使用 Gradle 实现一套代码开发多个应用
代码地址如下:http://www.demodashi.com/demo/11297.html 在文章 使用 Gradle 对应用进行个性化定制 中,我们能够针对一个应用的正式服.测试服.超管服等其他 ...
- 编译的时候找不到包 但是maven denpendencies已经有这个包 。或者myeclipse 为webroot eclipse为webContext需要修改
在Eclipse中生成项目是WebContent目录 而在MyEclipse中生成的项目目录名字好像叫做WebRoot,那么如果把MyEclipse的项目导入到Eclipse中,如果要部署项目到Tom ...
- python-循环(loop)-for循环
for 循环 for every_letter in 'Hello world': print(every_letter) 输出结果为 把 for 循环所做的事情概括成一句话就是:于...其中的每一个 ...
- 关于JSP和HTML
工作中,发现非常多同事不清楚JSP与HTML的生命周期.以至于出现"JavaScript为啥不能调用JSTL标签(或EL表达式)?"的笑话问题. 以下以流程图的方式.简单说明一下过 ...
- mysqli常用方法
//返回前一次 MySQL 操作(SELECT.INSERT.UPDATE.REPLACE.DELETE)所影响的记录行数. //一个 > 0 的整数表示所影响的记录行数.0 表示没有受影响的记 ...
- Centos下源码安装git
1.centos下git版本太久了,才1.8几,而官方更新的还是很活跃的,于是我就想源码安装一个新版本. 2.首先到: https://github.com/git/git/releases 下载最新 ...
- [elk]logstash的grok匹配逻辑grok+date+mutate
重点参考: http://blog.csdn.net/qq1032355091/article/details/52953837 logstash的精髓: grok插件原理 date插件原理 kv插件 ...
- [svc]salt源码安装软件和yum安装软件
上面简单列出了源码安装的sls文件书写思路. 涉及到一些固定的思路:如, 1,拷贝 解压安装时候需要依赖tar.gz存在 如果已安装则无需再次安装. 2,启动脚本 加入chk时候需要文件存在,如果已添 ...
- DirectShow中写push模式的source filter流程 + 源码(内附具体凝视)
尽管网上已有非常多关于DirectShow写source filter的资料.只是非常多刚開始学的朋友总说讲的不是非常清楚(可能当中作者省略了很多他觉得简 单的过程).读者总希望看到象第一步怎么做,第 ...
- makefile之patsubst函数
格式:$(patsubst pattern,replacement,text) 名称:模式字符串替换函数--patsubst. 功能:查找text中的单词(单词以"空格".&quo ...