自己实现了一个简单的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. Python-装饰器进阶

    基本概念 具体概念请先看之前的文章 理解装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理, Web权限校验, Cache等. 很有名的例子,就 ...

  2. 批量删除git分支

    本篇文章由:http://xinpure.com/bulk-delete-git-branching/ 批量删除git分支 使用 git 时候,经常会发现,不知不觉就创建了大量的分支.那么,麻烦事就来 ...

  3. jq的form验证

    jQuery(document).ready(function(){ $('#cform img.contact-loader').hide(); $('#cform').submit(functio ...

  4. Cocos2d-x开发---关于安卓打包所遇到的错误记录

         非常久都没有在安卓打过包了.之前的项目因为某些问题没有考虑做安卓版本号,所以涉及到安卓打包的时候都是自己在折腾.      这段时间离职了,空余时间就有非常多了.所以我能够折腾点事了.想起来 ...

  5. mysql init_connect

    init_connect 服务器为每个连接的客户端执行的字符串.字符串由一个或多个SQL语句组成.要想指定多个语句,用分号间隔开.例如,每个客户端开始时默认启用autocommit模式.没有全局服务器 ...

  6. Atitit. Class  元数据的反射操作 api apache  工具

    Atitit. Class  元数据的反射操作 api apache  工具 1 BeanUtils & PropertyUtils & MethodUtils类使用方法 - 短裤党  ...

  7. TomEE

    https://tomee.apache.org/ Apache TomEE, pronounced "Tommy", is an all-Apache Java EE 6 Web ...

  8. linux系统的开机引导、启动流程

    固件(CMOS/BIOS) > POST 加电自检 ↓ 自举程序(GRUB)> 加载内核 ↓ 载入内核 > 驱动硬件 ↓ 启动进程 init ↓ 读取执行配置文件/etc/initt ...

  9. @Transactional spring事务无效的解决方案

    关于@Transactional注解 一般都认为要注意以下三点 1 .在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义 ...

  10. PHP学习笔记(15)PDO数据库操作+AJAX无刷新技术删除用户

    pdo.php <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...