LinkedList
实现的原理应该是双链表,因为空链表的情况应该是header节点的前一节点和后一节点均为null。如果是循环链表,空链表应该头节点的头尾指针指向自己 。
首先注意链表的数据结构写法
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;
}
}
1.LinkedList linkedList = new LinkedList();
有两个构造器,默认构造器为空,带参构造器无非调用addAll()方法
2.linkedList.add(1);
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) //如果第一次添加,这里有可能为null,因此应该是双链表
first = newNode; //头结点
else
l.next = newNode;//修改后继指针
size++;
modCount++;
}
3.linkedList.addAll(linkedList1);
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
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;
}
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;
}
4. linkedList.set(1,1);
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;
}
}
5. linkedList.remove();
public E remove() {
return removeFirst();
}
//很明显要删除第一个节点
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;
}
6.get();
public E get(int index) {
checkElementIndex(index);
//还是老套路,根据索引遍历到节点
return node(index).item;
}
7.linkedList.indexOf(1)
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;
}
8.linkedList.remove(0)
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;
}
9. linkedList.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++;
}