`

深入JDK源代码之LinkedList类

 
阅读更多
public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, SerializableList 

   接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。

    此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。
    所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。
   注意,此实现不是同步的。如果多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法来“包装”该列表。最好在创建时完成这一操作,以防止对列表进行意外的不同步访问,如下所示:

  
List list = Collections.synchronizedList(new LinkedList(...));

    此类的 iterator 和 listIterator 方法返回的迭代器是快速失败 的:在迭代器创建之后,如果从结构上对列表进行修改,除非通过迭代器自身的 remove 或 add 方法,其他任何时间任何方式的修改,迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来不确定的时间任意发生不确定行为的风险。

    注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何硬性保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

  一、JDK中LinkedList总体实现:Linked实际上是一个双向链表,链表的每个节点是一个Entry对象,而Entry对象有一个previous引用和next引用。LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将[color=red][b]链接列表用作堆栈、队列或双端队列。
 
 public class LinkedList<E> extends AbstractSequentialList<E> implements
		List<E>, Deque<E>, Cloneable, java.io.Serializable {
	//列表头
	private transient Entry<E> header = new Entry<E>(null, null, null);
	private transient int size = 0;

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

	public LinkedList(Collection<? extends E> c) {
		this();
		addAll(c);
	}

	// 获取链表头
	public E getFirst() {
		if (size == 0)
			throw new NoSuchElementException();

		return header.next.element;
	}

	// 获取链表尾
	public E getLast() {
		if (size == 0)
			throw new NoSuchElementException();

		return header.previous.element;
	}

	// 移除表头
	public E removeFirst() {
		return remove(header.next);
	}

	// 移除表尾
	public E removeLast() {
		return remove(header.previous);
	}

	// 在表头添加
	public void addFirst(E e) {
		addBefore(e, header.next);
	}

	// 在表尾添加
	public void addLast(E e) {
		addBefore(e, header);
	}

	public boolean contains(Object o) {
		return indexOf(o) != -1;
	}

	public int size() {
		return size;
	}

	// 将指定元素添加到此列表的结尾。
	public boolean add(E e) {
		addBefore(e, header);
		return true;
	}

	//从此列表中移除首次出现的指定元素(如果存在)。
	public boolean remove(Object o) {
		if (o == null) {
			for (Entry<E> e = header.next; e != header; e = e.next) {
				if (e.element == null) {
					remove(e);
					return true;
				}
			}
		} else {
			for (Entry<E> e = header.next; e != header; e = e.next) {
				if (o.equals(e.element)) {
					remove(e);
					return true;
				}
			}
		}
		return false;
	}
   //添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。
	public boolean addAll(Collection<? extends E> c) {
		return addAll(size, c);
	}

	public boolean addAll(int index, Collection<? extends E> c) {
		if (index < 0 || index > size)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
					+ size);
		Object[] a = c.toArray();
		int numNew = a.length;
		if (numNew == 0)
			return false;
		modCount++;

		Entry<E> successor = (index == size ? header : entry(index));
		Entry<E> predecessor = successor.previous;
		for (int i = 0; i < numNew; i++) {
			Entry<E> e = new Entry<E>((E) a[i], successor, predecessor);
			predecessor.next = e;
			predecessor = e;
		}
		successor.previous = predecessor;

		size += numNew;
		return true;
	}

	/**
	 * Removes all of the elements from this list.
	 */
	public void clear() {
		Entry<E> e = header.next;
		while (e != header) {
			Entry<E> next = e.next;
			e.next = e.previous = null;
			e.element = null;
			e = next;
		}
		header.next = header.previous = header;
		size = 0;
		modCount++;
	}

	// Positional Access Operations 位置访问操作

	public E get(int index) {
		return entry(index).element;
	}

	public E set(int index, E element) {
		Entry<E> e = entry(index);
		E oldVal = e.element;
		e.element = element;
		return oldVal;
	}

	public void add(int index, E element) {
		addBefore(element, (index == size ? header : entry(index)));
	}

	public E remove(int index) {
		return remove(entry(index));
	}

	/**
	 * Returns the indexed entry.
	 */
	private Entry<E> entry(int index) {
		if (index < 0 || index >= size)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
					+ size);
		Entry<E> e = header;
		if (index < (size >> 1)) {
			for (int i = 0; i <= index; i++)
				e = e.next;
		} else {
			for (int i = size; i > index; i--)
				e = e.previous;
		}
		return e;
	}

	public int indexOf(Object o) {
		int index = 0;
		if (o == null) {
			for (Entry e = header.next; e != header; e = e.next) {
				if (e.element == null)
					return index;
				index++;
			}
		} else {
			for (Entry e = header.next; e != header; e = e.next) {
				if (o.equals(e.element))
					return index;
				index++;
			}
		}
		return -1;
	}

	public int lastIndexOf(Object o) {
		int index = size;
		if (o == null) {
			for (Entry e = header.previous; e != header; e = e.previous) {
				index--;
				if (e.element == null)
					return index;
			}
		} else {
			for (Entry e = header.previous; e != header; e = e.previous) {
				index--;
				if (o.equals(e.element))
					return index;
			}
		}
		return -1;
	}

	//从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。
	public boolean removeFirstOccurrence(Object o) {
		return remove(o);
	}

	//从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。
	public boolean removeLastOccurrence(Object o) {
		if (o == null) {
			for (Entry<E> e = header.previous; e != header; e = e.previous) {
				if (e.element == null) {
					remove(e);
					return true;
				}
			}
		} else {
			for (Entry<E> e = header.previous; e != header; e = e.previous) {
				if (o.equals(e.element)) {
					remove(e);
					return true;
				}
			}
		}
		return false;
	}
	
	public ListIterator<E> listIterator(int index) {
		return new ListItr(index);
	}
	private class ListItr implements ListIterator<E> {
		private Entry<E> lastReturned = header;
		private Entry<E> next;
		private int nextIndex;
		private int expectedModCount = modCount;

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

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

		public E next() {
			checkForComodification();
			if (nextIndex == size)
				throw new NoSuchElementException();

			lastReturned = next;
			next = next.next;
			nextIndex++;
			return lastReturned.element;
		}

		public boolean hasPrevious() {
			return nextIndex != 0;
		}

		public E previous() {
			if (nextIndex == 0)
				throw new NoSuchElementException();

			lastReturned = next = next.previous;
			nextIndex--;
			checkForComodification();
			return lastReturned.element;
		}

		public int nextIndex() {
			return nextIndex;
		}

		public int previousIndex() {
			return nextIndex - 1;
		}

		public void remove() {
			checkForComodification();
			Entry<E> lastNext = lastReturned.next;
			try {
				LinkedList.this.remove(lastReturned);
			} catch (NoSuchElementException e) {
				throw new IllegalStateException();
			}
			if (next == lastReturned)
				next = lastNext;
			else
				nextIndex--;
			lastReturned = header;
			expectedModCount++;
		}

		public void set(E e) {
			if (lastReturned == header)
				throw new IllegalStateException();
			checkForComodification();
			lastReturned.element = e;
		}

		public void add(E e) {
			checkForComodification();
			lastReturned = header;
			addBefore(e, next);
			nextIndex++;
			expectedModCount++;
		}

		final void checkForComodification() {
			if (modCount != expectedModCount)
				throw new ConcurrentModificationException();
		}
	}

	private static class Entry<E> {
		E element;
		Entry<E> next;
		Entry<E> previous;

		Entry(E element, Entry<E> next, Entry<E> previous) {
			this.element = element;
			this.next = next;
			this.previous = previous;
		}
	}

	private Entry<E> addBefore(E e, Entry<E> entry) {
		Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);
		newEntry.previous.next = newEntry;
		newEntry.next.previous = newEntry;
		size++;
		modCount++;
		return newEntry;
	}

	private E remove(Entry<E> e) {
		if (e == header)
			throw new NoSuchElementException();

		E result = e.element;
		e.previous.next = e.next;
		e.next.previous = e.previous;
		e.next = e.previous = null;
		e.element = null;
		size--;
		modCount++;
		return result;
	}

	/**
	 * @since 1.6
	 */
	public Iterator<E> descendingIterator() {
		return new DescendingIterator();
	}

	/** Adapter to provide descending iterators via ListItr.previous */
	private class DescendingIterator implements Iterator {
		final ListItr itr = new ListItr(size());

		public boolean hasNext() {
			return itr.hasPrevious();
		}

		public E next() {
			return itr.previous();
		}

		public void remove() {
			itr.remove();
		}
	}

	/**
	 * Returns a shallow copy of this <tt>LinkedList</tt>. (The elements
	 * themselves are not cloned.)
	 * 
	 * @return a shallow copy of this <tt>LinkedList</tt> instance
	 */
	public Object clone() {
		LinkedList<E> clone = null;
		try {
			clone = (LinkedList<E>) super.clone();
		} catch (CloneNotSupportedException e) {
			throw new InternalError();
		}

		// Put clone into "virgin" state
		clone.header = new Entry<E>(null, null, null);
		clone.header.next = clone.header.previous = clone.header;
		clone.size = 0;
		clone.modCount = 0;

		// Initialize clone with our elements
		for (Entry<E> e = header.next; e != header; e = e.next)
			clone.add(e.element);

		return clone;
	}

	public Object[] toArray() {
		Object[] result = new Object[size];
		int i = 0;
		for (Entry<E> e = header.next; e != header; e = e.next)
			result[i++] = e.element;
		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 (Entry<E> e = header.next; e != header; e = e.next)
			result[i++] = e.element;

		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 {
		// Write out any hidden serialization magic
		s.defaultWriteObject();

		// Write out size
		s.writeInt(size);

		// Write out all elements in the proper order.
		for (Entry e = header.next; e != header; e = e.next)
			s.writeObject(e.element);
	}

	private void readObject(java.io.ObjectInputStream s)
			throws java.io.IOException, ClassNotFoundException {
		// Read in any hidden serialization magic
		s.defaultReadObject();

		// Read in size
		int size = s.readInt();

		// Initialize header
		header = new Entry<E>(null, null, null);
		header.next = header.previous = header;

		// Read in all elements in the proper order.
		for (int i = 0; i < size; i++)
			addBefore((E) s.readObject(), header);
	}
}


二、LinkedList实现的队列操作
// Queue operations.队列操作

	// 获取但不移除此列表的头(第一个元素)。
	public E peek() {
		if (size == 0)
			return null;
		return getFirst();
	}

	// 获取但不移除此列表的头(第一个元素)。
	public E element() {
		return getFirst();
	}

	//获取并移除此列表的头(第一个元素)
	public E poll() {
		if (size == 0)
			return null;
		return removeFirst();
	}

	// 获取并移除此列表的头(第一个元素)。
	public E remove() {
		return removeFirst();
	}

	//将指定元素添加到此列表的末尾(最后一个元素)。
	public boolean offer(E e) {
		return add(e);
	}

三、LinkedList实现的双端队列操作
// Deque operations //双端队列操作
	
	
	// 在此列表的开头插入指定的元素。
	public boolean offerFirst(E e) {
		addFirst(e);
		return true;
	}

	
	// 在此列表的末尾插入指定的元素。
	public boolean offerLast(E e) {
		addLast(e);
		return true;
	}

	// 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
	public E peekFirst() {
		if (size == 0)
			return null;
		return getFirst();
	}

	// 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
	public E peekLast() {
		if (size == 0)
			return null;
		return getLast();
	}

	// 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
	public E pollFirst() {
		if (size == 0)
			return null;
		return removeFirst();
	}

	 //获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
	public E pollLast() {
		if (size == 0)
			return null;
		return removeLast();
	}
	

四、LinkedList实现的堆栈操作
//堆栈操作
	
	//入栈,将元素推入此列表所表示的堆栈。
	public void push(E e) {
		addFirst(e);
	}
    //出栈
	public E pop() {
		return removeFirst();
	}
0
5
分享到:
评论

相关推荐

    java jdk 宝典 源代码

    总之,Java JDK源代码是开发者不可或缺的学习资料,它为我们打开了Java世界的大门,让我们能够深入探究这个平台的内在运作机制。无论是为了学习、调试还是创新,都应该充分利用这些宝贵的资源,不断提升自己的技术...

    java-jdk源代码免费分享 src.zip

    Java JDK源代码是Java开发人员深入理解平台内部工作原理、优化代码和解决问题的重要参考资料。这份名为"src.zip"的压缩包文件包含了Java Development Kit的源代码,为开发者提供了丰富的学习和研究材料。以下是对...

    《Java 2 入门经典 JDK5》 源代码

    这个源代码在http://www.wrox.com上可以获得,并且还有课后习题的答案以及JDK5到JDK6的变动说明,甚至还有书中LinkedList类的纠正版本。(都在压缩包里的Beg_Java_15文件夹里) 但是为了学习JAVA我自己亲自把书上...

    jdk1.7源代码

    《深入解析JDK1.7源代码》 Java开发人员在面对面试时,经常会遇到关于JDK源码的问题。然而,对于大多数开发者来说,能够详细解答这些源码问题的人并不多。阅读并理解JDK源码,无疑能提升我们的技术水平,增强问题...

    jdk-1.6.0 源代码 三

    《深入解析JDK 1.6.0源代码——第三部分》 JDK 1.6.0作为Java发展史上的一座里程碑,它的源代码对于理解Java编程语言、虚拟机工作原理以及Java类库的实现至关重要。源代码的深度学习能够帮助开发者提升编程技艺,...

    java JDK 实例开发宝典 源代码

    在深入探讨源代码之前,我们需要了解Java JDK的基本组成部分: 1. **Java Runtime Environment (JRE)**:这是Java程序运行的基础,包括Java虚拟机(JVM)、类库和其他运行时需要的组件。 2. **Java Compiler ...

    java jdk 实例宝典 源代码

    这份源代码提供了丰富的示例,帮助开发者深入理解Java语言的使用和内部工作原理。通过研究这些实例,我们可以学习到如何有效地运用Java进行程序设计,提升编程技能。 首先,Java JDK是Java开发工具包,包含了Java...

    JDK实例开发宝典 例子 源代码 ,很经典的

    这份压缩包中包含了丰富的源代码,旨在帮助开发者深入理解和运用Java JDK的各种工具和类库,从而提升开发效率和代码质量。下面我们将详细探讨其中可能涵盖的一些关键知识点。 1. **基础语法与数据类型**:Java的...

    Java JDK 实例宝典 源代码

    源代码是学习编程最直观的方式,每个实例都充分展示了JDK在实际应用中的运用,同时,良好的编程风格和详尽的注释使得这些示例更易于理解和学习。 1. **基础语法与数据类型**:JDK实例中涵盖了Java的基础语法,包括...

    jdk1.6 源码jdk1.6 源码

    深入理解JDK 1.6的源码对于Java开发者来说至关重要,因为它揭示了语言核心库的工作原理,有助于优化代码、理解和解决潜在问题。 1. **Java虚拟机(JVM)**:JDK 1.6中的JVM是Java程序执行的基础,它的主要职责是...

    Java JDK实例宝典(夏先波著)书的所有源代码

    这本书的源代码是学习过程中非常宝贵的实践资源,能够使读者在理论与实践中更好地掌握Java技术。 1. **Java基础** - **类与对象**:书中源码涵盖了面向对象编程的基础,包括类的定义、对象的创建与销毁、封装、...

    Java全部源代码

    Java源代码包含了JDK(Java Development Kit)的所有组件,包括核心类库如java.lang、java.util、java.io等,这些类库构成了Java平台的基础。通过阅读源代码,我们可以了解到Java的API是如何实现的,比如对象的创建...

    jdk源码 jdk源码

    它包含了许多关键组件的源代码,使开发者能够深入探索Java语言的底层实现,从而提升编程技巧,优化性能,并理解标准库的工作原理。在这个压缩包中,我们可以看到多个目录,如`com`, `org`, `launcher`, `java`, `...

    Java 1.6 源代码

    Java 1.6 源代码是Java开发者深入理解Java平台核心类库的重要参考资料。它包含了许多关键组件的实现细节,比如集合框架、输入/输出流、多线程、网络编程以及反射等核心功能。通过研读源代码,开发者可以学习到如何...

    javajdk源码-java.util_source_learning:学习JDK源代码

    在Java编程领域,深入理解JDK源代码是提升开发技能的关键步骤。`java.util`包是Java标准库的核心部分,包含了大量的工具类和集合框架,是日常开发中频繁使用的组件。`java.util_source_learning`项目提供了对JDK源码...

    Java2实用教程第5版源代码.rar

    通过这些源代码,读者可以深入学习并实践书中所讲解的知识点。 1. **第一章**:通常会介绍Java的基础知识,包括Java的历史、开发环境的搭建(如JDK的安装和配置)、第一个Java程序的编写以及编译和运行过程。通过`...

    java jdk实列宝典 光盘源代码

    java为数据结构中的列表定义了一个接口类java.util.list同时提供了3个实现类,分别是ArrayList、Vector、LinkedList使用; 生成不重复的随机数序列;列表、集合与数组的互相转换;java为数据结构中的映射定义一个接口...

    java学习笔记JDK6.0课件和代码

    通过这个JDK 6.0的学习笔记和源代码,你不仅可以学习到Java的基础知识,还能通过实际案例理解如何在项目中运用这些知识。随着Java技术的不断发展,虽然JDK 6.0已经过时,但它仍然是初学者理解和掌握Java编程思想的...

    达内IT培训java源代码1

    在“达内IT培训java源代码1”中,我们可能看到的是Java的基础应用,包括类、对象、方法、变量等概念。 1. 类与对象:在Java中,一切皆为对象,而类是创建对象的蓝图。类定义了对象的属性(数据成员)和行为(方法)...

    Java源代码编程的基础知识

    以上只是Java源代码编程基础知识的一部分,实际学习过程中,还会涉及到接口、枚举、反射、JNI等更深入的话题。Java教程,如`javanotes5.1.1`,通常会逐步引导你理解和掌握这些概念,从而成为熟练的Java开发者。

Global site tag (gtag.js) - Google Analytics