自己实现了一个简单的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实现的更多相关文章

  1. Flink源码分析 - 剖析一个简单的Flink程序

    本篇文章首发于头条号Flink程序是如何执行的?通过源码来剖析一个简单的Flink程序,欢迎关注头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech) ...

  2. Java-链表LinkedList源码原理分析,并且通过LinkedList构建队列

    在这里我们介绍一下最简单的链表LinkedList: 看一下add()方法: public boolean add(E e) { linkLast(e); return true; } void li ...

  3. 转:【Java集合源码剖析】LinkedList源码剖析

    转载请注明出处:http://blog.csdn.net/ns_code/article/details/35787253   您好,我正在参加CSDN博文大赛,如果您喜欢我的文章,希望您能帮我投一票 ...

  4. java基础解析系列(十)---ArrayList和LinkedList源码及使用分析

    java基础解析系列(十)---ArrayList和LinkedList源码及使用分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder jav ...

  5. 【java集合框架源码剖析系列】java源码剖析之LinkedList

    注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本. 在实际项目中LinkedList也是使用频率非常高的一种集合,本博客将从源码角度带领大家学习关于LinkedList的知识. ...

  6. Java集合:LinkedList源码解析

    Java集合---LinkedList源码解析   一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据re ...

  7. Java集合之LinkedList源码解析

    LinkedList简介 LinkedList基于双向链表,即FIFO(先进先出)和FILO(先进后出)都是支持的,这样它可以作为堆栈,队列使用 继承AbstractSequentialList,该类 ...

  8. Java泛型底层源码解析-ArrayList,LinkedList,HashSet和HashMap

    声明:以下源代码使用的都是基于JDK1.8_112版本 1. ArrayList源码解析 <1. 集合中存放的依然是对象的引用而不是对象本身,且无法放置原生数据类型,我们需要使用原生数据类型的包 ...

  9. 【源码阅读】Java集合之二 - LinkedList源码深度解读

    Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章; 本文是第二篇LinkedList. ---@pdai JDK版 ...

随机推荐

  1. sql server 使用for xml path 将1列多行转换为字符串连接起来

    create table tb ([id] )) insert into tb ,'aa' union all ,'bb' union all ,'cc' union all ,'dd' union ...

  2. 代码收藏系列--jquery--筛选器、事件绑定技巧(转载)

    代码收藏系列--jquery--筛选器.事件绑定技巧 Jquery筛选器的一些常用技巧,比如过滤属性等 /* 过滤获取没有含data-xsui-grid-colspan的节点 */$(this).fi ...

  3. C# Oracle.ManagedDataAccess 批量更新表数据

    这是我第一次发表博客.以前经常到博客园查找相关技术和代码,今天在写一段小程序时出现了问题, 但在网上没能找到理想的解决方法.故注册了博客园,想与新手分享(因为本人也不是什么高手). vb.net和C# ...

  4. LNMP架构二

    Nginx默认虚拟主机 1.首先修改nginx.conf文件,删除server及下面的,在http最后添加include vhost/*.conf; (指定虚拟主机目录,并读取以.conf结尾的文件) ...

  5. .NET面试题(三)

    第1讲:面试前期准备 1.了解相关技术职务需要的技术人才                              2.准备一份出色的个人简历 第2讲:面试前期准备                   ...

  6. django如何修改开发服务器的端口

    我们启动django开发服务器,输入命令 manage.py  runserver  默认的端口是8000. 我们在浏览器中输入127.0.0.1:8000,可以访问8000端口 我们先停掉djang ...

  7. 实验c语言不同类型的指针互用(不推荐只是学习用)

    #include <stdio.h> int main(int argc, char *argv[]) { printf("Hello, world\n"); ]; i ...

  8. unity, 判断可见性

    如果一个物体被unity判定为”退一万步讲也一定不可见“,则unity不会去渲染它,但是如果我们给此物体添加了逻辑,这个逻辑仍然会被执行. 因此,假如这个逻辑是巨耗性能的逻辑,比如说”mesh的每个顶 ...

  9. JUC组件扩展(二)-JAVA并行框架Fork/Join(一):简介和代码示例

    一.背景 虽然目前处理器核心数已经发展到很大数目,但是按任务并发处理并不能完全充分的利用处理器资源,因为一般的应用程序没有那么多的并发处理任务.基于这种现状,考虑把一个任务拆分成多个单元,每个单元分别 ...

  10. NGUI的一个bug记录

    在当前帧内触发按钮事件,然后把click事件的list删去,再添加,这时候会再次触发. 不确定,先记一下