JDK源码中只包含了一个header节点,各有利弊。
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<E> {
public LinkedList() {
clear();
}
/**
* 清空链表
*/
public void clear() {
this.head = new Node<E>(null, null, null);
this.tail = new Node<E>(null, head, null);
this.head.next = tail;
this.size = 0;
}
/**
* 返回链表大小
*
* @return 大小
*/
public int size() {
return this.size;
}
/**
* 链表是否为空
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* 添加元素e,在末尾
*/
public boolean addLast(E e) {
add(size(), e);
return true;
}
public boolean addFirst(E e) {
add(0, e);
return true;
}
/**
* 在index位置插入元素e
*/
public void add(int index, E e) {
addBefore(getNode(index), e);
}
/**
* 获取index位置元素
*/
public E get(int index) {
return getNode(index).data;
}
public E getFirst() {
if (size() == 0) {
throw new NoSuchElementException();
}
return head.next.data;
}
public E getLast() {
if (size() == 0) {
throw new NoSuchElementException();
}
return tail.prev.data;
}
public boolean contains(E e) {
return indexOf(e) > 0;
}
public int indexOf(E e) {
Node<E> p = head.next;
int i = 0;
while (p.next != null) {
if (p.data.equals(e)) {
return i;
}
p = p.next;
i++;
}
return -1;
}
/**
* 将index位置的元素设置为e
*/
public E set(int index, E e) {
Node<E> node = getNode(index);
E oldValue = node.data;
node.data = e;
return oldValue;
}
/**
* 移除idnex位置的元素
*/
public E remove(int index) {
return remove(getNode(index));
}
public E removeFirst() {
return remove(head.next);
}
public E removeLast() {
return remove(tail.prev);
}
/**
* 在p节点前添加元素e
*/
private void addBefore(Node<E> p, E e) {
Node<E> newNode = new Node<E>(e, p.prev, p);
p.prev.next = newNode;
p.prev = newNode;
size++;
}
/**
* 移除节点p
*/
private E remove(Node<E> p) {
p.next.prev = p.prev;
p.prev.next = p.next;
size--;
return p.data;
}
/**
* 获取index为位置的节点
*/
private Node<E> getNode(int index) {
if (index < 0 || index > size) {
throw new IndexOutOfBoundsException();
}
Node<E> p;
if (index < (size >> 1)) {
p = head.next;
for (int i = 0; i < index; i++) {
p = p.next;
}
} else {
p = tail;
for (int i = size(); i > index; i--) {
p = p.prev;
}
}
return p;
}
/**
* 返回LinkedList迭代器
*/
public Iterator<E> iterator() {
return new Iterator<E>() {
private Node<E> current = head.next;
private boolean canRemove = false;
@Override
public boolean hasNext() {
return current != tail;
}
@Override
public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
E value = current.data;
current = current.next;
canRemove = true;
return value;
}
@Override
public void remove() {
if (!canRemove) {
throw new IllegalStateException();
}
LinkedList.this.remove(current.prev);
canRemove = true;
}
};
}
private int size;
private Node<E> head;
private Node<E> tail;
private static class Node<E> {
public E data;
public Node<E> prev;
public Node<E> next;
public Node(E e, Node<E> prev, Node<E> next) {
this.prev = prev;
this.next = next;
this.data = e;
}
}
}
import static org.junit.Assert.*;
import java.util.Iterator;
import org.junit.Test;
public class LinkedListTest {
@Test
public void testClear() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.clear();
int expectedSize = 0;
assertEquals(expectedSize, list.size());
}
@Test
public void testSize1() {
LinkedList<Integer> list = new LinkedList<Integer>();
int expected = 0;
assertEquals(expected, list.size());
}
@Test
public void testSize2() {
testClear();
}
@Test
public void testIsEmpty() {
LinkedList<Integer> list = new LinkedList<Integer>();
boolean expected = true;
assertEquals(expected, list.isEmpty());
}
@Test
public void testAddE() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(1);
list.addLast(1);
int expected = 6;
assertEquals(expected, list.size());
}
@Test
public void testAddIntE() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.add(0, 1);
int expected = 1;
assertEquals(expected, list.get(0).intValue());
}
@Test
public void testGet() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
int expected = 6;
assertEquals(expected, list.get(5).intValue());
}
@Test
public void testSet() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
list.set(2,-1);
assertEquals(-1, list.get(2).intValue());
}
@Test
public void testRemove1() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
list.remove(5);
Iterator<Integer> itr = list.iterator();
int i = 1;
while(itr.hasNext()){
assertEquals(i++, itr.next().intValue());
}
}
@Test
public void testRemove() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
list.remove(5);
Iterator<Integer> itr = list.iterator();
int i = 1;
while(itr.hasNext()){
assertEquals(i++, itr.next().intValue());
}
}
@Test
public void testIterator() {
LinkedList<Integer> list = new LinkedList<Integer>();
list.addLast(1);
list.addLast(2);
list.addLast(3);
list.addLast(4);
list.addLast(5);
list.addLast(6);
Iterator<Integer> itr = list.iterator();
int i = 1;
while(itr.hasNext()){
assertEquals(i++, itr.next().intValue());
}
}
}