PerKins Zhu

Le vent se lève,il faut tenter de vivre.

导航

源码解读—LinkedList

Posted on 2016-08-18 17:15  PerKins.Zhu  阅读(257)  评论(0编辑  收藏  举报

学习了一下linkedList的源码,做下记录.
  java底层实现的是双向环链表,程序定义了一个header,来保存头结点,header.next指向最后一个节点(最后插入到),header.prevoious指向第一个节点(最先插入的)。

链表中的节点是通过Entry 来充当节点的:

  Entry是一个 private static 约束的内部类

 

初始化的时候造了个环,以后的所有操作就在环中进行。

在进行插入或者删除时需要查找的时候,由于是双向链表,那么由哪头开始进行查找呢?看代码

可见。如果位置小于size的一半就从尾(最后插入的地方)开始查找,大于一半从头(最先插入的地方)开始查找。

 

添加、删除、查找没什么可说的,就是引用的替换。

LinkedList 可以通过迭代器进行迭代,主要是Collection继承了Iterable

在LinkedList中添加了一个内部类ListItr实现了linkedList的迭代输出。

调用结构如下:

      link.iterator();       找到AbstractSequentialList中的iterator()方法,返回ListItr对象。

     linkedList中实现了ListItr ,所以 link.iterator();便把linkedList中的ListItr给返回过去了。

     linkedList在ListItr实现了接口Iterator,同时实现了三个方法(hasNext(),next(),remove())。

这里涉及到子类的继承和接口的实现,特别是子类对父类的方法覆写,不是太明白的话可以好好研究研究。

 

 程序中有段循环挺溜的,贴出来分享一下:这是查找某个数据在链表中的位置。

 

根据源码简单的实现了一下linkedList的基本功能代码如下:

package com.zpj.LinkedList;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class LinkedList<T> implements Iterable<T> {

	private static class Node<T> {
		Node<T> previous;
		Node<T> next;
		T data;

		public Node(Node<T> previous, Node<T> next, T data) {
			super();
			this.previous = previous;
			this.next = next;
			this.data = data;
		}
	}

	private Node<T> head = new Node<T>(null, null, null);
	private int size = 0;

	public LinkedList() {
		head.previous = head.next = head;
	}

	public boolean add(T data) {
		return addData(data, head);
	}

	private boolean addData(T data, Node<T> node) {
		if (data == null) {
			return false;
		}
		Node<T> tempNode = new Node<T>(node, node.next, data);
		node.next.previous = tempNode;
		node.next = tempNode;
		size++;
		return true;
	}

	public T get(int index) {
		Node<T> node = head.next;
		if (index < 0 || index > size)
			throw new IndexOutOfBoundsException("");
		if (index < (size >> 1)) {
			for (int i = 0; i < index; i++) {
				node = node.next;
			}
		} else {
			for (int i = size; i > index; i--) {
				node = node.previous;
			}
		}
		return node.data;
	}

	private class ListItr implements Iterator<T> {
		private Node<T> lastReturnNode;
		private Node<T> nextNode;
		private int nextIndex;

		public ListItr(int index) {
			if (index < 0 || index > size)
				throw new IndexOutOfBoundsException("Index:" + index + ";size:" + size);
			if (index < (size >> 1)) {
				nextNode = head.next;
				for (nextIndex = 0; nextIndex < index; nextIndex++) {
					nextNode = nextNode.next;
				}
			} else {
				nextNode = head.previous;
				for (nextIndex = size; nextIndex > index; nextIndex--) {
					nextNode = nextNode.previous;
				}
			}
		}

		@Override
		public boolean hasNext() {
			return nextIndex != size;
		}

		@Override
		public T next() {
			if (nextIndex == size)
				throw new NoSuchElementException();
			lastReturnNode = nextNode;
			nextNode = nextNode.next;
			nextIndex++;
			return lastReturnNode.data;
		}

		@Override
		public void remove() {
		}
	}

	@Override
	public Iterator<T> iterator() {
		return new ListItr(0);
	}

}

 

LinkedList的实现本身不是很复杂,在这里只记录了一些自认为比较关键的几个点,如果想深入了解可以看下这篇博客http://www.cnblogs.com/ITtangtang/p/3948610.html  写的挺漂亮的!