LinkedList是常用的一种List的实现类,采取单向链表的结构
在LinkedList中,以一个内部的Node类来代表集合中的对象,对象的值赋给item属性,Node中的next属性指向当前对象的后一个对象,prev属性指向对象的前一个对象。同时也用了两个node属性,一个first代表链表的第一个元素
一个last代表链表的末尾,LinkedList具体实现方法如下:
一.LinedList继承结构
java.lang.Object
-java.util.AbstractCollection<E>
-java.util.AbstractList<E>
-java.util.AbstractSequentialList<E>
-java.util.LinkedList<E>
实现的接口:List<E>, Deque<E>, Cloneable, Serializable
二.实现方法介绍:
2.1 构造方法
~LinkedList() 默认构造器,创建一个空的list
~LinkedList(Collection<? extends E> c) 创建一个list,里面包含指定集合中的所有元素
2.2 add 插入对象
~void addFirst(E e) 在开头添加元素
~void addLast(E e) 在末尾添加元素
~void add(E element) 在末尾添加指定的元素
~void add(int index, E element) 在指定的索引位置,增加指定的元素
~public boolean addAll(Collection<? extends E> c) 插入集合中的所有对象
~public boolean addAll(int index, Collection<? extends E> c) 在指定位置插入集合中的对象
源码分析:
public boolean add(E e) {
linkLast(e);
return true ;
}
往list末尾添加一个对象
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++;
}
获取末尾对象,创建一个新的node对象,node的prev指向末尾元素,如果末尾为空,即这个list中还未添加对象,则将first指向newNode,否则添加到末尾。
LinkedList的add方法不用考虑像arrayList一样进行扩容和复制数据的问题,但是每增加一个数据,都需要创建一个新的Node<E> 对象
2.3 remove 删除对象
~E removeFirst() 删除链表的第一个对象,返回删除的对象
~E removeLast() 删除链表的最后一个对象
~boolean remove(Object o) 删除指定的对象
~E remove(int index) 删除指定位置的对象
~E remove() 调用removeFirst
public boolean remove(Object o) {
//判断删除的对象是否为null
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 ;
}
E unlink (Node<E> x) {
// 获取指定对象的属性
final E element = x.item ;
final Node<E> next = x.next ;
final Node<E> prev = x.prev ;
//判断是否为首元素
if (prev == null) {
first = next;
} else {
//把x从链表中去掉
prev. next = next;
x. prev = null;
}
if (next == null) {
last = prev;
} else {
next. prev = prev;
x. next = null;
}
//x的属性都赋值为空,让GC处理掉
x. item = null;
size--;
modCount++;
return element;
}
LinkedList删除元素比ArrayList简单很多,毕竟ArrayList将当前元素所在位置后的元素通过复制往前移动一位
2.4 get 获取对象
~E get(int index) 获取指定位置的元素
~E getFirst() 获取首元素
~E getLast() 获取末尾元素
源码分析:
public E get (int index) {
//入参检验
checkElementIndex(index);
return node(index).item ;
}
Node<E> node (int index) {
// 判断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;
}
}
LinkedList的元素是存放到链表里面的,所以get操作相对ArrayList来说要复杂一些
2.5 contains 判断集合中是否存在这个元素
~boolean contains(Object o)
三.LinkedList总结
~jdk1.7 中的linkedList采用单向链表的方式实现
~LinkedList在插入元素的时候需要创建一个新的node对象,在查找元素的时候需要遍历链表,在删除元素的时候,要遍历链表,找到指定的元素进行删除
~LinkedList是非线程安全的