LinkedList双向链表源码分析
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
/**
* @author 小黄debug on 2022/3/10
* @version 1.0
*/
public class LinkedListCRUD {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
linkedList.add(1);
linkedList.add(2);
linkedList.add(3);
System.out.println("linkedList = " + linkedList);
System.out.println("----------------------分隔线---------------------");
//删除一个结点
//linkedList.remove(); //这里默认删除的是第一个结点
linkedList.remove(2);
System.out.println("linkedList = " + linkedList);
System.out.println("----------------------分隔线---------------------");
//修改某个结点
linkedList.set(1,999); //这里的1是指的结点下标
System.out.println("linkedList = "+linkedList);
System.out.println("----------------------分隔线---------------------");
//因为LinkedList实现了list接口,遍历方式
Iterator iterator = linkedList.iterator();
while(iterator.hasNext()){
Object next = iterator.next();
System.out.println("next = " + next);
}
System.out.println("----------------------分隔线---------------------");
//增强for
for (Object o : linkedList) {
System.out.println(o);
}
System.out.println("----------------------分隔线---------------------");
//普通for
for(int i = 0; i < linkedList.size(); i++){
System.out.println(linkedList.get(i));
}
//源码阅读
/*
1、LinkedList linkedList = new LinkedList();
进来
public LinkedList() {
}
1.1、这时linkedList的属性first = null、 last = null、 size = 0
2、执行添加add
public boolean add(E e) {
linkLast(e); // ->
return true;
}
2.1、将新的结点,加入到双向链表的最后
void linkLast(E e) {
final Node<E> l = last; //l临时存储最后一个结点
final Node<E> newNode = new Node<>(l, e, null); //1、这里将新结点的pre指向原来的结点 ,由于原来的结点在第一次时不存在, // ->
last = newNode; //将last指向新结点
if (l == null) //由于原来的最后一个结点为空,所以将first指向新结点
first = newNode; //也说明该结点的next为null
else
l.next = newNode; //2.如果原来的结点存在,则将原来的结点next指赂新结点
size++; //大小增加
modCount++;
}
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
3、默认删除remove
public E remove() {
return removeFirst();
}
public E removeFirst() {
final LinkedList.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 LinkedList.Node<E> next = f.next; //获取下一结点
f.item = null; //将当前节点信息置空
f.next = null; // help GC //将当前节点的next置空
first = next; //将first指向下一结点
if (next == null) //当下一结点为空时
last = null; //将last置空
else
next.prev = null; //否则将下一结点的pre设置为null
size--; //size-1
modCount++;
return element; //返回被删除的节点信息
}
//4、删除指定的结点remove(index)
public E remove(int index) {
checkElementIndex(index); //判断该index是否存在
return unlink(node(index));
}
LinkedList.Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
LinkedList.Node<E> x = first;
for (int i = 0; i < index; i++) //此处通过for循环拿到下标为index的结点
x = x.next;
return x;
} else {
LinkedList.Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final LinkedList.Node<E> next = x.next;
final LinkedList.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;
}
//5、修改某个结点set(index,element)
public E set(int index, E element) {
checkElementIndex(index); //判断是否存在下标为index的结点
LinkedList.Node<E> x = node(index); //通过遍历获取到这个结点
E oldVal = x.item;
x.item = element; //更新结点信息
return oldVal; //返回原来的结点信息
}
*/
}
}