LinkedList和ArrayList一样实现了List接口

  • ArrayList内部为数组
  • LinkedList内外为双向链表
  • 实现了Deque接口,双端列队的实现

  • 图片来自Wiki

内部实现为Node对象

private static class Node<E> {
E item;
Node<E> next;
Node<E> prev; Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
  • LinkedList都一个元素都知道它上一个和下一个元素的地址
  • next属性表示下一个元素对象
  • prev属性表示上一个元素对象
  • item属性为当前元素对象

属性

transient int size = 0;
transient Node<E> first;
transient Node<E> last;
  • 不能被序列化

add方法

public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
  • 原来last属性改为e
  • 如果原last对象为空,则第一个元素为新元素
  • 如果原last对象的next元素改为新元素

addFirst方法

private void linkFirst(E e) {
final Node<E> f = first;
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
  • 只改了原first元素的上一个元素地址
  • addList,只改了原last元素的下一个元素地址

set方法

public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
  • 索引是按循环查找的
  • 就近原则
  • 原来的元素会返回

indexOf方法

public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
  • equals比较

toArray方法

public Object[] toArray() {
Object[] result = new Object[size];
int i = 0;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item;
return result;
} public <T> T[] toArray(T[] a) {
if (a.length < size)
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
for (Node<E> x = first; x != null; x = x.next)
result[i++] = x.item; if (a.length > size)
a[size] = null; return a;
}

clear方法

public void clear() {
for (Node<E> x = first; x != null; ) {
Node<E> next = x.next;
x.item = null;
x.next = null;
x.prev = null;
x = next;
}
first = last = null;
size = 0;
modCount++;
}
  • 所有都被清空

get方法

public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
  • 使用了循环

remove方法

public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}

remove索引

public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev; if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
} if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
} x.item = null;
size--;
modCount++;
return element;
}

remove object

public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}

结论:

  • 不带索引的操作都是比较快的,比如add、removeFirst等
  • 链表是往后添加的
  • 可以从前、后添加\移除数据
  • 可以当堆栈、队列或双端队列操作

干了这杯Java之LinkedList的更多相关文章

  1. 干了这杯Java之ArrayList

    List存储一个有序元素合集 List接口的实现类有: ArrayList,LinkedList,Vector,Stack ArrayList一个数组型的List 默认容量为10 private st ...

  2. 干了这杯java之ThreadLocal

    ThreadLocal Java篇 是什么 怎么用 源码 缺点 总结 是什么 ThreadLocal是一个关于创建线程局部变量的类,这个变量只能当前线程使用,其他线程不可用. ThreadLocal提 ...

  3. 干了这杯Java之集合概览

    Java集合框架支持两种类型容器: 一种是为了存储一个元素的合集,为Collection 一种是为了存储键/值对,为Mapping Collection包含 Set存储不重复的元素 List存储一个有 ...

  4. 干了这杯Java,让你的Idea比eclipse好用

    1.Idea基本配置 1.1 Idea简介 Idea是一个专门针对Java的集成开发工具(IDE),由Java语言编写.所以,需要有JRE运行环境并配置好环境变量.简单的说,Idea是写代码用的工具. ...

  5. 干了这杯Java之Vector

    Vector实现了AbstractList抽象类和List接口,和ArrayList一样是基于Array存储的 Vector 是线程安全的,在大多数方法上存在synchronized关键字 //Vec ...

  6. 干了这杯Java之HashMap

    类: public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneab ...

  7. 干了这杯Java之transient关键字

    看源码的时候,发现transient这个关键字,不甚理解,查找资料发现:不被序列化 疑问: 静态变量是不是不被序列化? public class User implements Serializabl ...

  8. 蓝桥杯java试题《洗牌》

    问题描述 小弱T在闲暇的时候会和室友打扑克,输的人就要负责洗牌.虽然小弱T不怎么会洗牌,但是他却总是输. 渐渐地小弱T发现了一个规律:只要自己洗牌,自己就一定会输.所以小弱T认为自己洗牌不够均匀,就独 ...

  9. 内功心法 -- java.util.LinkedList<E> (1)

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------下文主要对java.util ...

随机推荐

  1. Beta的计划和人员的变动

    一.新的成员和组长是否重选: 刘光华:先加入的一个帅哥,乐于助人,编码基础不是很好,但是有一颗热爱学习的心,会积极主动的完成自己的任务的,一句话宣言:我们的团队是最棒的! 程志铭:做事认真负责,工作脚 ...

  2. java课程设计--We Talk(201521123061)

    java课程设计--We Talk(201521123061) 团队博客链接:http://www.cnblogs.com/slickghost/ 数据库 一.通过Dao模式建立与数据库的连接 1.数 ...

  3. 201521123081《Java程序设计》 第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 参考资料:XMind 2. 书面作业 本次PTA作业题集异常.多线程. Q1. finally 题目4-2 ...

  4. geyear和getfullyear的区别

    getYear(),IE中获得正确年份,但有的浏览器获取的是当前年份-1900的值.而IE是当大于2000时,直接加上1900 getFullYear(),都是可以获得正确年份. 所以建议使用getF ...

  5. 生成验证码JSP【复用代码】

    该JSP可以生成验证码.以后用到的时候就方便了. <%@ page language="java" pageEncoding="UTF-8"%> & ...

  6. 《Head First Java》读书笔记(2) - Java面向对象思想

    1.了解继承 对象继承实际上就是一种"is - a"的关系,如上图的"PantherMan is a SuperHero?",是,那么便属于继承的理解. 继承能 ...

  7. MapReduce极简教程

    一个有趣的例子 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃?   MapReduce方法则是: 给在座的所有玩家中分配这摞牌 让每个玩家数自己手中的牌有几张是黑桃,然后 ...

  8. 以下内容对于灵活修改textField中文本以及占位文本属性进行了完整的封装,加入项目中可以节约开发时间。

    textField对占位文本设置属性有限,在项目中需要改变占位文本的属性以及位置,需要自己对控件进行封装 封装方法如下: 在LDTextField.m 文件中: #import <UIKit/U ...

  9. css样式引入优先级?

    css中的优先级讲的有 1.选择器的优先级. 2.样式引入的优先级. 今天要研究的是样式引入的优先级.网上又很多答案都是如下的,但是真的是这样的吗,让我们来探一探究竟是如何. 四种样式的优先级别是:行 ...

  10. 翻译连载 | 第 9 章:递归(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...