`
zy19982004
  • 浏览: 661843 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
F6f66edc-1c1a-3859-b76b-a22e740b7aa7
Hadoop学习
浏览量:251950
社区版块
存档分类
最新评论

容器学习八:LinkedList源码分析

 
阅读更多

 一.概述

  1. LinkedList继承Deque,所以LinkedList的插入删除操作遵循先进性出FIFO。
  2. LinkedList继承Deque,所以Linkedist实现了Deque的操作,比喻offer peek pollfirst/last等操作。其实这些操作也就是建立在getFirst getLast addFirst addLast removeFirst removeLast这几个操作上的。

 

.成员变量

	//头节点
	private transient Entry<E> header = new Entry<E>(null, null, null);
	private transient int size = 0;

 

.节点Entry对象

	//节点
	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;
		}
	}
 

 四.构造函数

	//初始化
	public LinkedList() {
		header.next = header.previous = header;
	}
 

.存数据

	//默认插入到最后
	public boolean add(E e) {
		addBefore(e, header);
		return true;
	}
	
	//把元素e插入最前
	public void addFirst(E e) {
		//等价于把元素e插入到原第一个节点header.next的前面
		addBefore(e, header.next);
	}

	//把元素e插入最后
	public void addLast(E e) {
		//等价于把元素e插入到header的前面,因为是双链表
		addBefore(e, header);
	}
	
	//在指定位置插入元素e,原index处和以后的元素往后移
	public void add(int index, E element) {
		//index == size,把元素e插入到header的前面
		//其他情况把元素e插入entry(index)的前面
		addBefore(element, (index == size ? header : entry(index)));
	}

	
	//把元素e插入到指定entry的前面
	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;
	}
 

.取数据

	//取指定位置的元素
	public E get(int index) {
		return entry(index).element;
	}
	
	private Entry<E> entry(int index) {
		if (index < 0 || index >= size)
			throw new IndexOutOfBoundsException("Index: " + index + ", Size: "
					+ size);
		Entry<E> e = header;
		//在链表中取值时,需要遍历整个链表,
		//即使优化成遍历半个链表,相对于ArrayList的随机访问,还是慢的
		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 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;
	}

	//和ArrayList一样的算法,只是ArrayList遍历数组,LinkedList遍历链表
	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;
	}

 

 六.删数据

	//remove默认删除第一个位置的元素
	public E remove() {
		return removeFirst();
	}
	
	public E removeFirst() {
		return remove(header.next);
	}
	
	public E removeLast() {
		return remove(header.previous);
	}
	
	//和ArrayList一样的算法,只是ArrayList遍历数组,LinkedList遍历链表
	public boolean remove(Object o) {
		if (o == null) {
			for (Entry<E> e = header.next; e != header; e = e.next) {
				if (e.element == null) {
				    //转换成remove(Entry)
					remove(e);
					return true;
				}
			}
		} else {
			for (Entry<E> e = header.next; e != header; e = e.next) {
				if (o.equals(e.element)) {
					//转换成remove(Entry)
					remove(e);
					return true;
				}
			}
		}
		return false;
	}
	
	//转换成remove(Entry)
	public E remove(int index) {
		return remove(entry(index));
	}
	
	//删除指定节点:删除操作都将落到这个方法上
	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;
	}
 

.遍历

private class ListItr implements ListIterator<E> {
		private Entry<E> lastReturned = header;
		private Entry<E> next;
		private int nextIndex;
		private int expectedModCount = modCount;

                //初始化的时候next = header.next;
		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;
		}
                //遍历的时候next = next.next,按照从头往后遍历,也就是FIFO的顺序
		public E next() {
			checkForComodification();
			if (nextIndex == size)
				throw new NoSuchElementException();

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

		
	}
 

 

 

分享到:
评论

相关推荐

    LinkedList源码学习分析

    《LinkedList源码学习分析》 LinkedList作为Java集合框架中的一员,是基于链表数据结构实现的线程不安全容器。本文将深入探讨LinkedList的实现原理、核心方法的代码实现,并对比ArrayList,理解其特性和使用场景。 ...

    JUC并发编程与源码分析视频课.zip

    《JUC并发编程与源码分析视频课》是一门深入探讨Java并发编程的课程,主要聚焦于Java Util Concurrency(JUC)库的使用和源码解析。JUC是Java平台提供的一组高级并发工具包,它极大地简化了多线程编程,并提供了更...

    免费开源-【Java学习+面试指南】部分内容大部分是Java程序员所需要掌握的核心知识

    Unsafe 详细解Java SPI 机制详解Java语法糖详解集合知识点/面试题总结:Java集合常见知识点&面试题总结(上)(必看)Java集合常见知识点&面试题总结(下)(必看)Java容器使用注意事项总结源码分析:ArrayList核心...

    【Java学习+面试指南】 一份涵盖大部分Java程序员所需要掌握的核心知识

    源码分析: ArrayList 核心源码+扩容机制分析 LinkedList 核心源码分析 HashMap 核心源码+底层数据结构分析 ConcurrentHashMap 核心源码+底层数据结构分析 LinkedHashMap 核心源码分析 CopyOnWriteArrayList 核心...

    Java容器总结

    源码分析有助于理解其设计模式和事件驱动机制。 3. **EJB(Enterprise JavaBeans)**:在企业级应用中,EJB容器负责管理事务、安全性和资源,提供服务器端组件的生命周期管理。EJB有三种类型:session beans、...

    Java源码分析:集合-容器.pdf

    Queue接口定义了先进先出的队列操作,LinkedList实现了Queue接口,因此可以作为一个队列来使用。除了基本的队列操作外,Java还提供了PriorityQueue等具有优先级功能的队列。 在Java集合框架中,各种集合类型的自动...

    javaSourceLearn:jdk源码构建

    List、Set、Map三大接口以及其实现类(ArrayList、LinkedList、HashSet、TreeSet、HashMap、LinkedHashMap等)的源码分析能帮助我们更高效地利用数据结构,优化程序性能。 标签“系统开源”表明这个项目鼓励开放和...

    JAVA容器效率深度分析List

    本文将深入分析Java中的List接口及其常见的实现类,如ArrayList、LinkedList和Vector,探讨它们的效率差异和适用场景。 首先,List是Java集合框架中的一个重要接口,它扩展了Collection接口,并规定了元素的有序性...

    Java 容器.pdf_电子版pdf版

    源码分析 ArrayList 是一个基于动态数组实现的 List 实现类。它实现了 RandomAccess 接口,因此支持随机访问。ArrayList 的默认大小为 10,添加元素时使用 ensureCapacityInternal() 方法来保证容量足够,如果不够...

    androidjava源码-Android-Knowledge:Android源码和Java知识总结

    - **集合框架**:ArrayList、LinkedList、HashMap等容器的实现细节和性能对比。 - **异常处理**:理解Checked和Unchecked异常,以及如何优雅地处理异常。 - **多线程与并发**:线程的创建、同步机制...

    Java项目学习库,SprintBoot源码解析

    在"java-study-master"这个压缩包中,可能包含了上述知识点的实践示例和详细讲解,包括代码结构、配置文件、源码分析等,可以帮助学习者深入理解Java和SpringBoot的使用。通过系统地学习和实践,开发者可以提升自己...

    2021最新Java基础面试,0~1年小白专属,部分附源码分析.7z

    Java编程语言作为软件开发领域的重要组成部分,对于初学者而言,掌握其...同时,由于资源中提及部分附带源码分析,学习者可以通过实际代码来加深理解,遇到问题还能获得答疑支持,这对于新手来说是一份极其宝贵的资料。

    JAVA容器对象整理

    这些知识点仅仅是Java容器对象的一部分,实际的博客可能会包含更多细节,如源码分析、性能对比和最佳实践。通过阅读博客中的`持有对象.xmind`文件,可以进一步了解博主对这些概念的详细整理和分类。如果你对Java容器...

    java核心技术源码(第八版)

    通过源码分析,可以更深入地理解这些概念的实际应用。 2. **异常处理**:学习如何使用try-catch-finally语句处理程序运行时可能出现的异常,以及如何自定义异常类。 3. **集合框架**:包括ArrayList、LinkedList、...

    java核心卷I源码

    《Java核心卷I源码》是一本专注于Java编程语言核心概念和技术的教材,其源代码提供了深入理解Java语言原理的机会。...对于那些已经有一定经验的开发者,源码分析也是提升技术水平和代码质量的重要途径。

    Java核心技术结合源码验证

    源码分析可以帮助你理解它们的内部工作原理,如扩容策略、查找和插入效率等。 4. **多线程**:Java提供了丰富的API来支持多线程编程,如Thread类和Runnable接口。通过源码,你可以学习如何创建和管理线程,以及同步...

    java容器源码-Java-Container-Source-Code:Java常用容器底层源码及注释

    本项目“Java-Container-Source-Code”专注于Java常用容器的底层源码分析,提供了对这些容器实现的深入理解。源码分析对于开发者来说至关重要,因为它可以帮助我们了解内部的工作机制,优化代码性能,以及解决潜在的...

    study1010_bursttpf_java学习_源码.zip

    3. **集合框架**:ArrayList、LinkedList、HashSet、HashMap等容器的使用,以及泛型的理解。 4. **IO流**:学习如何读写文件,理解字节流和字符流的区别,以及缓冲区的概念。 5. **多线程**:线程的创建、同步机制...

    Java核心技术第八版源码

    《Java核心技术》第八版是学习Java的权威指南,涵盖了广泛的主题,包括基础知识、类库、并发、网络编程等。本压缩包包含了该书的源代码,分为卷I和卷II两部分,方便读者结合理论深入理解Java的实现原理。 卷I的源码...

    Java核心技术(第八版)源码

    《Java核心技术(第八版)源码》是Java编程学习者的重要参考资料,包含了Java语言的核心概念和技术。这本书分为上下两卷,全面覆盖了Java的基础到高级主题。随书附带的源码是理解并实践书中理论知识的关键,为读者提供...

Global site tag (gtag.js) - Google Analytics