LinkedList源码学习

1、如何基于双向链表实现LinkedList

2、双向链表有什么特性

3、源码是如何实现快速获取表头表尾的

4、双向链表循环条件是怎么样的,以及如何判断表头表尾

5、源码中迭代器如何实现的

/**
*基于双向链表
*/

public class LinkedList<E> extends AbstractSequentialList<E> 
implements List<E>,Deque<E>, Cloneable, java.io.Serializable{
	transient int size = 0;
	
	//链表的表头
	transient Node<E> first;
	
	//链表表尾
	transient Node<E> last;
	
	//构造器
	public LinkedList(){
	}
	
	public LinkedList(Collection<? extends E> c){
		this();
		addAll(c);
	}
	
	//从表头添加元素,若为空表,则直接加在表尾
	private void linkFirst(E e){
		final Node<E> f = first;
		final Node<E> newNode = new Node<>(null, e, f);
		first = newNode;
		if(f == null)
		   last = newNode;
		else
		   f.prev = newNode;
		size++;
		modCount++;
	}
	
	//从表尾添加元素,若为空表,则直接赋值给表头
	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++;		
	}
	
	//向一个非空后继节点前插入一个节点
	void linkBefore(E e, Node<E> succ){
		//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++;
	}
	
	//删掉非空头节点,并返回元素
	private E unlinkFirst(Node<E> f){
	//f == first && f != null
		final E element = f.item;
		final Node<E> next = f.next;
		f.item = null;
		f.next = null;
		first = next;
		if(next == null)
		   last = null;
		else
		   next.prev = null;
		size--;
		modCount++;
		return element;
	}
	
	//删除非空尾结点
	private E unlinkLast(Node<E> l){
		//l == last && l != null
		final E element = l.item;
		final Node<E> pred = l.prev;
		l.item = null;
		l.prev = null;
		last = pred;
		if(pred == null)
		   first = null;
		else
		   pred.next = null;
		size--;
		modCount++;
		return element;
	}
	
	//删除非空节点
	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{
			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;
	}
	
	//获取头结点
	public E getFirst(){
		final Node<E> f = first;
		if(f == null)
		   throw new NoSuchElementException();
		return f.item;
	}
	
	//获取尾结点
	public E getLast(){
		final E l = last;
		if(l == null)
		   throw new NoSuchElementException();
		return l.item;
	}
	
	//删除并返回第一个元素
	public E removeFirst(){
		final Node<E> f = first;
		if(f == null)
		   throw new NoSuchElementException();
		return unlinkFirst(f);
	}
	
	//删除并返回最后一个元素
	public E removeLast(){
		final E l = last;
		if(l == null)
		   throw new NoSuchElementException();
		return unlinkLast(l);
	}
	
	//在头结点处插入元素
	public voi addFirst(E e){
		linkFirst(e);
	}
	
	//删除指定元素
	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 boolean addAll(Collection<? extends E> c){
		addAll(size, c);
	}
	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 = newNode;
		}else {
		   pred.next = succ;
		   succ.prev = pred;
		}

        size++;
        modCount++;
        return true;		
	}
	
	//清空
	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++;
	}
	
	//根据索引获取集合元素
	public E get(int index){
		checkElementIndex(index);
		return node(index).item;
	}
	
	//根据索引设置集合元素并返回旧值
	public E set(int index, E element){
		checkElementIndex(index);
		Node<E> x = node(index);
		E oldVal = x.item;
		x.item = element;
		return oldVal;
	}
	
	//检查下标,索引从0开始
	private boolean isElementIndex(int index){
		return index >= 0 && index < size;
	}
	
	//插入位置检查
	private boolean isPositionElement(int index){
		return index >= 0 && index <= size;
	}
	
	private String outOfBoundsMsg(int index){
		return "Index:" + index + ", Size:" + size;
	}
	
	private void checkElementIndex(int index){
		if(!isElementIndex(index){
			throw new IndexOutOfBoundsException(outOfBoundsMsg);
		}
	}
	
	private void checkPositionIndex(int index){
		if(!isPositionElement(index)){
			throw new IndexOutOfBoundsException(outOfBoundsMsg);
		}
	}
	
	/**
	*返回指定索引处节点,使用了快速检索方法,利用了
	*双向链表的特性,可以从前往后也可以从后往前检索
	*/
	Node<E> node(int 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;
		}
	}
	
	//返回第一次出现指定元素的索引
	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){
		int index = size;
		if(o == null){
           for(Node<E> x = last; x != null; x = x.prev){
			  index--;
              if(x.item == null)
				  return index;
		   }		   
		}else{
			index--;
			if(o.equals(x.item))
			   return index;
		}
		return -1;
	}
	
	//获取头结点值但不删除
	public E peek(){
		final Node<E> f = first;
		return (f == null) ? null : f.item;
	}
	
	//获取头结点值且删除
	public E poll(){
		final Node<E> f = first;
		return (f == null) ? null : unlinkFirst(f);
	}
	
	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;
		}
	}
	
	//迭代器
	public ListIterator<E> listIterator(int index){
		checkPositionIndex(index);
		return new ListItr(index);
	}
	private class ListItr implements ListIterator<E> {
		private Node<E> lastReturned;
		private Node<E> next;
		private int nextIndex;
		private int expectedModCount = modCount;
		
		ListItr(int index){
			next = (index == size) ? null : node(index);
			nextIndex = index;
		}
		
		public boolean hasNext(){
			return nextIndex < size;
		}
		
		public E next(){
			checkForComodification();
			if(!hasNext())
				throw new NoSuchElementException();
		
		    lastReturned = next;
			next = next.next;
			nextIndex++;
			return lastReturned.item;
		}
		
		public boolean hasPrevious(){
			//只要不是表头就有prev
			return nextIndex > 0;
		}
		
		public E previous(){
			checkForComodification();
			if(!hasPrevious())
			   throw new NoSuchElementException();
			
			lastReturned = next = (next == null) ? last : next.prev;
			nextIndex--;
			return lastReturned.item;
		}
		
		public int nextIndex(){
			return nextIndex;
		}
		
		public int previousIndex(){
			return nextIndex - 1;
		}
		
		public void remove(){
           checkForComodification();
           if(lastReturned == null)
              throw new IllegalStateException();
         
           Node<E> lastNext = lastReturned.next;
		   unlink(lastReturned);
		   
		   if(next == lastReturned)
		      next = lastNext;
		   else
		      nextIndex--;
		   lastReturned = null;
		   expectedModCount++;
		}
		
		public void set(E e){
			if(lastReturned == null)
			   throw new IllegalStateException();
			checkForComodification();
			lastReturned.item = e;
		}
		
		public void add(E e){
			checkForComodification();
			lastReturned = null;
			if(next == null)
			   linkLast(e);
			else
			   linkBefore(e, next);
			nextIndex++;
			expectedModCount++;
		}
		
	  public void forEachRemaining(Consumer<? super E> action) {
		Objects.requireNonNull(action);
		while (modCount == expectedModCount && nextIndex < size) {
			action.accept(next.item);
			lastReturned = next;
			next = next.next;
			nextIndex++;
		}
		checkForComodification();
	}
		
		final void checkForComodification(){
			if(modCount != expectedModCount)
			   throw new ConcurrentModificationException();
		}
	}
	
	private LinkedList<E> superClone(){
		try{
			return (LinkedList<E>)super.clone();
		}catch(CloneNotSupportedException e){
			throw new InternalError(e);
		}
	}
	
	public Object clone(){
		LinkedList<E> clone = superClone();
		
		clone.first = clone.last = null;
		clone.size = 0;
		clone.modCount = 0;
		
		for(Node<E> x = first; x != null; x = x.next){
			clone.add(x.item);
		}
		
		return clone;
	}
	
	public Object[] toArray(){
		Object[] result = new Object[size];
		int i = 0;
		for(Node<E> x = first; x != null; x = x.next){
			result[i++] = x.item;
		}
		
		return result;
	}
	
    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;
    }
	
	private static final long serialVersionUID = 876323262645176354L;
	
	private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
		s.defaultWriteObject();
		
		s.writeInt(size);
		
		for(Node<E> x = first; x != null; x = x.next)
		   s.writeObject(x.item);
	}
	
	private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException{
		s.defaultReadObject();
		
		int size = s.readInt();
		for(int i = 0; i < size; i ++)
		   linkLast((E)s.readObject());
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值