一、概念
类定义:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
- 继承了AbstractSequentialList抽象类,实现了List接口,拥有一组List通用的操作。
- 实现了Deque接口,可当做双端队列使用。
- 实现了Cloneable接口,可进行浅层次拷贝。
- 实现了Serializable接口,可进行序列化。
特点:
- 长于在List中间插入和删除元素。
- 随机访问元素较慢。
二、使用
//TestLinkedList
public class TestLinkedList {
private static final String TAG = "TestLinkedList";
private LinkedList<String> list = new LinkedList<>();
public void testAdd() {
list.add("a");
list.add("b");
list.add("c");
Log.d(TAG, "zwm, add list: " + list);
}
public void testAddFirst() {
list.addFirst("first");
Log.d(TAG, "zwm, addFirst list: " + list);
}
public void testAddLast() {
list.addLast("last");
Log.d(TAG, "zwm, addLast list: " + list);
}
public void testAdd2() {
list.add(0, "ii");
list.add(1, "jj");
list.add(2, "kk");
Log.d(TAG, "zwm, add index list: " + list);
}
public void testAddAll() {
LinkedList<String> temp = new LinkedList<>();
temp.add("lll");
temp.add("mmm");
temp.add("nnn");
list.addAll(temp);
Log.d(TAG, "zwm, addAll list: " + list);
}
public void testAddAll2() {
LinkedList<String> temp = new LinkedList<>();
temp.add("xxxx");
temp.add("zzzz");
temp.add("yyyy");
temp.add("zzzz");
list.addAll(0, temp);
Log.d(TAG, "zwm, addAll index list: " + list);
}
public void testGet() {
Log.d(TAG, "zwm, get index 2: " + list.get(2));
}
public void testGetFirst() {
Log.d(TAG, "zwm, getFirst: " + list.getFirst());
}
public void testGetLast() {
Log.d(TAG, "zwm, getLast: " + list.getLast());
}
public void testIndexOf() {
Log.d(TAG, "zwm, indexOf zzzz: " + list.indexOf("zzzz"));
}
public void testLastIndexOf() {
Log.d(TAG, "zwm, lastIndexOf zzzz: " + list.lastIndexOf("zzzz"));
}
public void testClone() {
LinkedList<String> cloneList = (LinkedList)list.clone();
Log.d(TAG, "zwm, list.equals(cloneList): " + list.equals(cloneList));
Log.d(TAG, "zwm, list==cloneList: " + (list==cloneList));
}
public void testContains() {
Log.d(TAG, "zwm, contains zzzz: " + list.contains("zzzz"));
}
public void testContainsAll() {
LinkedList<String> temp = new LinkedList<>();
temp.add("xxxx");
temp.add("yyyy");
temp.add("zzzz");
Log.d(TAG, "zwm, containsAll: " + list.containsAll(temp));
}
public void testSize() {
Log.d(TAG, "zwm, size: " + list.size());
}
public void testClear() {
list.clear();
Log.d(TAG, "zwm, clear list: " + list);
}
public void testEmpty() {
Log.d(TAG, "zwm, isEmpty: " + list.isEmpty());
}
public void testIterator() {
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
Log.d(TAG, "zwm, iterator item: " + iterator.next());
}
}
public void testIterator2() {
ListIterator<String> iterator = list.listIterator();
while (iterator.hasNext()) {
String item = iterator.next();
Log.d(TAG, "zwm, listIterator item: " + item);
if(TextUtils.equals(item, "b")) {
Log.d(TAG, "zwm, remove b");
iterator.remove();
} else if(TextUtils.equals(item, "c")) {
Log.d(TAG, "zwm, update c to x");
iterator.set("x");
}
}
Log.d(TAG, "zwm, listIterator list: " + list);
Log.d(TAG, "zwm, next index: " + iterator.nextIndex());
Log.d(TAG, "zwm, previous index: " + iterator.previousIndex());
while(iterator.hasPrevious()) {
String item = iterator.previous();
Log.d(TAG, "zwm, listIterator item: " + item);
}
}
public void testIterator3() {
ListIterator<String> iterator = list.listIterator(2);
while (iterator.hasNext()) {
String item = iterator.next();
Log.d(TAG, "zwm, listIterator index item: " + item);
}
}
public void testDescendingIterator() {
Iterator<String> descendingIterator = list.descendingIterator();
while (descendingIterator.hasNext()) {
Log.d(TAG, "zwm, descendingIterator item: " + descendingIterator.next());
}
}
public void testRemove() {
Log.d(TAG, "zwm, remove a: " + list.remove("a"));
Log.d(TAG, "zwm, remove list: " + list);
}
public void testRemove2() {
Log.d(TAG, "zwm, remove index 3: " + list.remove(3));
Log.d(TAG, "zwm, remove index list: " + list);
}
public void testRemove3() {
Log.d(TAG, "zwm, remove: " + list.remove());
Log.d(TAG, "zwm, remove list: " + list);
}
public void testRemoveFirst() {
list.removeFirst();
Log.d(TAG, "zwm, removeFirst list: " + list);
}
public void testRemoveLast() {
list.removeLast();
Log.d(TAG, "zwm, removeLast list: " + list);
}
public void testRemoveAll() {
LinkedList<String> temp = new LinkedList<>();
temp.add("a");
temp.add("b");
Log.d(TAG, "zwm, removeAll: " + list.removeAll(temp));
Log.d(TAG, "zwm, removeAll list: " + list);
}
public void testElement() {
Log.d(TAG, "zwm, element: " + list.element());
Log.d(TAG, "zwm, element list: " + list);
}
public void testRetainAll() {
LinkedList<String> temp = new LinkedList<>();
temp.add("a");
temp.add("b");
temp.add("c");
Log.d(TAG, "zwm, retainAll: " + list.retainAll(temp));
Log.d(TAG, "zwm, retainAll list: " + list);
}
public void testSet() {
list.set(0, "sss");
Log.d(TAG, "zwm, set list: " + list);
}
public void testSubList() {
//以下注释语句会抛出异常java.lang.ClassCastException: java.util.SubList cannot be cast to java.util.LinkedList
//LinkedList<String> subList = (LinkedList<String>)list.subList(1, 2);
List<String> subList = list.subList(1, 3);
Log.d(TAG, "zwm, subList: " + subList);
}
public void testToArray() {
Object[] arrays = list.toArray();
for(Object item : arrays) {
Log.d(TAG, "zwm, toArray item: " + item);
}
}
public void testToArray2() {
String[] param = new String[list.size()];
String[] result = list.toArray(param);
for(String item : param) {
Log.d(TAG, "zwm, toArray T param item: " + item);
}
for(String item : result) {
Log.d(TAG, "zwm, toArray T result item: " + item);
}
}
//LinkedList实现栈 start
public void testPushStack() {
list.push("AAAA");
list.push("BBBB");
list.push("CCCC");
list.push("DDDD");
Log.d(TAG, "zwm, push list: " + list);
}
public void testPeekStack() {
Log.d(TAG, "zwm, peek: " + list.peek());
Log.d(TAG, "zwm, peek list: " + list);
}
public void testPopStack() {
Log.d(TAG, "zwm, pop: " + list.pop());
Log.d(TAG, "zwm, pop list: " + list);
}
//LinkedList实现栈 end
//LinkedList实现队列 start
public void testOfferQueue() {
list.offer("AAAAA");
list.offer("BBBBB");
list.offer("CCCCC");
Log.d(TAG, "zwm, offer list: " + list);
}
public void testAddQueue() {
list.add("DDDDD");
list.add("EEEEE");
list.add("FFFFF");
Log.d(TAG, "zwm, add list: " + list);
}
public void testPeekQueue() {
Log.d(TAG, "zwm, peek: " + list.peek());
Log.d(TAG, "zwm, peek list: " + list);
}
public void testElementQueue() {
Log.d(TAG, "zwm, element: " + list.element());
Log.d(TAG, "zwm, element list: " + list);
}
public void testPollQueue() {
Log.d(TAG, "zwm, poll: " + list.poll());
Log.d(TAG, "zwm, poll list: " + list);
}
public void testRemoveQueue() {
Log.d(TAG, "zwm, remove: " + list.remove());
Log.d(TAG, "zwm, remove list: " + list);
}
//LinkedList实现队列 end
}
//测试代码
private void testMethod() {
Log.d(TAG, "zwm, testMethod");
TestLinkedList linkedList = new TestLinkedList();
linkedList.testAdd();
linkedList.testAddFirst();
linkedList.testAddLast();
linkedList.testAdd2();
linkedList.testAddAll();
linkedList.testAddAll2();
linkedList.testGet();
linkedList.testGetFirst();
linkedList.testGetLast();
linkedList.testIndexOf();
linkedList.testLastIndexOf();
linkedList.testClone();
linkedList.testContains();
linkedList.testContainsAll();
linkedList.testSize();
linkedList.testClear();
linkedList.testEmpty();
linkedList.testAdd();
linkedList.testIterator();
linkedList.testIterator2();
linkedList.testAdd();
linkedList.testIterator3();
linkedList.testDescendingIterator();
linkedList.testRemove();
linkedList.testRemove2();
linkedList.testRemove3();
linkedList.testRemoveFirst();
linkedList.testRemoveLast();
linkedList.testAdd();
linkedList.testRemoveAll();
linkedList.testAdd();
linkedList.testElement();
linkedList.testRetainAll();
linkedList.testSet();
linkedList.testSubList();
linkedList.testToArray();
linkedList.testToArray2();
linkedList.testClear();
linkedList.testPushStack();
linkedList.testPeekStack();
linkedList.testPopStack();
linkedList.testClear();
linkedList.testOfferQueue();
linkedList.testAddQueue();
linkedList.testPeekQueue();
linkedList.testElementQueue();
linkedList.testPollQueue();
linkedList.testRemoveQueue();
}
//输出log
2019-08-14 15:35:38.260 zwm, testMethod
2019-08-14 15:35:38.264 zwm, add list: [a, b, c]
2019-08-14 15:35:38.264 zwm, addFirst list: [first, a, b, c]
2019-08-14 15:35:38.264 zwm, addLast list: [first, a, b, c, last]
2019-08-14 15:35:38.265 zwm, add index list: [ii, jj, kk, first, a, b, c, last]
2019-08-14 15:35:38.266 zwm, addAll list: [ii, jj, kk, first, a, b, c, last, lll, mmm, nnn]
2019-08-14 15:35:38.266 zwm, addAll index list: [xxxx, zzzz, yyyy, zzzz, ii, jj, kk, first, a, b, c, last, lll, mmm, nnn]
2019-08-14 15:35:38.266 zwm, get index 2: yyyy
2019-08-14 15:35:38.266 zwm, getFirst: xxxx
2019-08-14 15:35:38.267 zwm, getLast: nnn
2019-08-14 15:35:38.267 zwm, indexOf zzzz: 1
2019-08-14 15:35:38.267 zwm, lastIndexOf zzzz: 3
2019-08-14 15:35:38.268 zwm, list.equals(cloneList): true
2019-08-14 15:35:38.268 zwm, list==cloneList: false
2019-08-14 15:35:38.268 zwm, contains zzzz: true
2019-08-14 15:35:38.268 zwm, containsAll: true
2019-08-14 15:35:38.268 zwm, size: 15
2019-08-14 15:35:38.268 zwm, clear list: []
2019-08-14 15:35:38.269 zwm, isEmpty: true
2019-08-14 15:35:38.269 zwm, add list: [a, b, c]
2019-08-14 15:35:38.269 zwm, iterator item: a
2019-08-14 15:35:38.269 zwm, iterator item: b
2019-08-14 15:35:38.269 zwm, iterator item: c
2019-08-14 15:35:38.269 zwm, listIterator item: a
2019-08-14 15:35:38.269 zwm, listIterator item: b
2019-08-14 15:35:38.269 zwm, remove b
2019-08-14 15:35:38.270 zwm, listIterator item: c
2019-08-14 15:35:38.270 zwm, update c to x
2019-08-14 15:35:38.270 zwm, listIterator list: [a, x]
2019-08-14 15:35:38.270 zwm, next index: 2
2019-08-14 15:35:38.270 zwm, previous index: 1
2019-08-14 15:35:38.270 zwm, listIterator item: x
2019-08-14 15:35:38.270 zwm, listIterator item: a
2019-08-14 15:35:38.271 zwm, add list: [a, x, a, b, c]
2019-08-14 15:35:38.271 zwm, listIterator index item: a
2019-08-14 15:35:38.271 zwm, listIterator index item: b
2019-08-14 15:35:38.271 zwm, listIterator index item: c
2019-08-14 15:35:38.271 zwm, descendingIterator item: c
2019-08-14 15:35:38.272 zwm, descendingIterator item: b
2019-08-14 15:35:38.272 zwm, descendingIterator item: a
2019-08-14 15:35:38.272 zwm, descendingIterator item: x
2019-08-14 15:35:38.272 zwm, descendingIterator item: a
2019-08-14 15:35:38.272 zwm, remove a: true
2019-08-14 15:35:38.272 zwm, remove list: [x, a, b, c]
2019-08-14 15:35:38.272 zwm, remove index 3: c
2019-08-14 15:35:38.273 zwm, remove index list: [x, a, b]
2019-08-14 15:35:38.273 zwm, remove: x
2019-08-14 15:35:38.273 zwm, remove list: [a, b]
2019-08-14 15:35:38.273 zwm, removeFirst list: [b]
2019-08-14 15:35:38.273 zwm, removeLast list: []
2019-08-14 15:35:38.273 zwm, add list: [a, b, c]
2019-08-14 15:35:38.274 zwm, removeAll: true
2019-08-14 15:35:38.274 zwm, removeAll list: [c]
2019-08-14 15:35:38.274 zwm, add list: [c, a, b, c]
2019-08-14 15:35:38.274 zwm, element: c
2019-08-14 15:35:38.275 zwm, element list: [c, a, b, c]
2019-08-14 15:35:38.275 zwm, retainAll: false
2019-08-14 15:35:38.275 zwm, retainAll list: [c, a, b, c]
2019-08-14 15:35:38.276 zwm, set list: [sss, a, b, c]
2019-08-14 15:35:38.276 zwm, subList: [a, b]
2019-08-14 15:35:38.276 zwm, toArray item: sss
2019-08-14 15:35:38.276 zwm, toArray item: a
2019-08-14 15:35:38.276 zwm, toArray item: b
2019-08-14 15:35:38.277 zwm, toArray item: c
2019-08-14 15:35:38.277 zwm, toArray T param item: sss
2019-08-14 15:35:38.277 zwm, toArray T param item: a
2019-08-14 15:35:38.277 zwm, toArray T param item: b
2019-08-14 15:35:38.277 zwm, toArray T param item: c
2019-08-14 15:35:38.277 zwm, toArray T result item: sss
2019-08-14 15:35:38.277 zwm, toArray T result item: a
2019-08-14 15:35:38.277 zwm, toArray T result item: b
2019-08-14 15:35:38.277 zwm, toArray T result item: c
2019-08-14 15:35:38.277 zwm, clear list: []
2019-08-14 15:35:38.278 zwm, push list: [DDDD, CCCC, BBBB, AAAA]
2019-08-14 15:35:38.278 zwm, peek: DDDD
2019-08-14 15:35:38.278 zwm, peek list: [DDDD, CCCC, BBBB, AAAA]
2019-08-14 15:35:38.278 zwm, pop: DDDD
2019-08-14 15:35:38.278 zwm, pop list: [CCCC, BBBB, AAAA]
2019-08-14 15:35:38.279 zwm, clear list: []
2019-08-14 15:35:38.279 zwm, offer list: [AAAAA, BBBBB, CCCCC]
2019-08-14 15:35:38.279 zwm, add list: [AAAAA, BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.279 zwm, peek: AAAAA
2019-08-14 15:35:38.280 zwm, peek list: [AAAAA, BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.280 zwm, element: AAAAA
2019-08-14 15:35:38.280 zwm, element list: [AAAAA, BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.280 zwm, poll: AAAAA
2019-08-14 15:35:38.280 zwm, poll list: [BBBBB, CCCCC, DDDDD, EEEEE, FFFFF]
2019-08-14 15:35:38.280 zwm, remove: BBBBB
2019-08-14 15:35:38.281 zwm, remove list: [CCCCC, DDDDD, EEEEE, FFFFF]
三、原理
重要参数
//当前结点个数
transient int size = 0;
//第一个结点
transient Node<E> first;
//最后一个结点
transient Node<E> last;
//链表结点类
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;
}
}
构造函数
//初始化时size为0,first和last的结点都为空
public LinkedList() {
}
//初始化时将Collection中的所有元素添加到链表中
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
public boolean add(E e)
//添加一个元素到链表末尾
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++;
}
public void add(int index, E element)
//在索引位置添加元素
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
public void addFirst(E e)
//添加一个元素到链表头部
public void addFirst(E e) {
linkFirst(e);
}
public void addLast(E e)
//添加一个元素到链表末尾
public void addLast(E e) {
linkLast(e);
}
public boolean addAll(Collection<? extends E> c)
//添加Collection中的所有元素到链表末尾
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
public boolean addAll(int index, Collection<? extends E> c)
//添加Collection中的所有元素到链表索引位置
public boolean addAll(int index, Collection<? extends E> c) {
checkPositionIndex(index);
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
Node<E> pred, succ;
if (index == size) {
succ = null;
pred = last;
} else {
succ = node(index);
pred = succ.prev;
}
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
public boolean remove(Object o)
//移除链表中与对象o相等的元素
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;
}
public E remove(int index)
//移除链表中索引位置的元素
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
public E removeFirst()
//移除第一个元素
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
public E removeLast()
//移除最后一个元素
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
public E get(int index)
//获取索引位置的元素
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
public E getFirst()
//获取链表表头元素
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
public E getLast()
//获取链表表尾元素
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
public E set(int index, E element)
//将index位置的元素更改为element
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
public int indexOf(Object o)
//从头到尾查找与对象o相等的元素的索引位置
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;
}
public int lastIndexOf(Object o)
//从尾到头查找与对象o相等的元素的索引位置
public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
}
public int size()
//获取链表元素个数
public int size() {
return size;
}
public void clear()
//清空链表
public void clear() {
// Clearing all of the links between nodes is "unnecessary", but:
// - helps a generational GC if the discarded nodes inhabit
// more than one generation
// - is sure to free memory even if there is a reachable Iterator
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++;
}
private class ListItr implements ListIterator<E>
private class DescendingIterator implements Iterator<E>
public void push(E e)
//将元素压入栈顶
public void push(E e) {
addFirst(e);
}
public E peek()
//获取栈顶元素
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
public E pop()
//移除栈顶元素
public E pop() {
return removeFirst();
}
public boolean offer(E e)
//将元素插入到队列尾部
public boolean offer(E e) {
return add(e);
}
public E element()
//获取队列头部元素
public E element() {
return getFirst();
}
public E poll()
//移除队列头部元素
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
网友评论