`
uule
  • 浏览: 6359492 次
  • 性别: Icon_minigender_1
  • 来自: 一片神奇的土地
社区版块
存档分类
最新评论

LinkedList源码总结

 
阅读更多

双向链表:http://student.zjzk.cn/course_ware/data_structure/web/xianxingbiao/xianxingbiao2.3.3.htm

源码解析1:http://www.iteye.com/topic/1115828

2: http://blog.csdn.net/moreevan/article/details/6783801

 


 

LinkedList属于一个双向循环的链表,其内部是用一个Entry来维护的

private transient Entry<E> header = new Entry<E>(null, null, null);

默认构造函数:

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

 

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;
	}
    }

 

  element:当前节点的值

  previous:指向当前节点的前一个节点

  next:指向当前节点的后一个节点

 

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

 

 /** 
      * 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;  
 } 

 

 /**  
 *将元素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;  
     }  
   
   
 /** 
 *删除给定的结点e 
 */  
     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;  
     }  
   
   
   
 /**  
 *从表头开始遍历,返回此元素在表中的第一个位置 
      */  
     public int indexOf(Object o) {  
         int index = 0;  
         if (o==null) { //如果传入的元素是null,则不能调用 eqauls方法进行比较  
             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 add(E e) {  
        addBefore(e, header); //加到头结点之前 ,即表尾  
         return true;  
     }  
   
 /** 
 *默认的删除动作是删除链表的第一个元素,所以说在默认情况下,LinkedList其实扮*演的是一个队列的角色 
 */  
 public E remove() {  
         return removeFirst();  
     }  
//LinkedList是如何序列化和反序列化的

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);
    }

    /**
     * Reconstitute this <tt>LinkedList</tt> instance from a stream (that is
     * deserialize it).
     */
    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);
    }

 

注意:

注意entry的循环

 for (Entry e = header.previous; e != header; e = e.previous) {}

 新节点的创建

Entry<E> newEntry = new Entry<E>(e, entry, entry.previous);

此时新加节点已知道其前后节点,但其前节点并不知道后节点发生变化,后节点也不知道前节点发生变化,所以分别将新节点赋给他们。

 

 

注意头结点的初始化  

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

 

 

 由index获取节点的entry(int index) 方法...

 

 

ArrayList中主要用到以下方法:

public static  T[] copyOf(T[] original, int newLength) {
    Object[] Arrays.copyOf(elementData, size);
    从数组elementData中复制size个元素到返回的新数组,不足时补null,否则截取
//Copies the specified array, truncating or padding with nulls 

 
System提供了一个静态方法arraycopy(),我们可以使用它来实现数组之间的复制 。其函数原型是:

public static void arraycopy(Object src,int srcPos, Object dest,int destPos, int length)
        //list中的remove(int index)方法就是调用该方法

//src:源数组;    srcPos:源数组要复制的起始位置;
//dest:目的数组;    destPos:目的数组放置的起始位置;
//length:复制的长度。

 

注意:src and dest都必须是同类型或者可以进行转换类型的数组.

有趣的是这个函数可以实现自己到自己复制,比如:
int[] fun ={0,1,2,3,4,5,6};
System.arraycopy(fun,0,fun,3,3);
则结果为:{0,1,2,0,1,2,6};
实现过程是这样的,先生成一个长度为length的临时数组,将fun数组中srcPos到srcPos+length-1之间的数据拷贝到临时数组中,再执行System.arraycopy(临时数组,0,fun,3,3).

 

  • 大小: 15.7 KB
分享到:
评论

相关推荐

    LinkedList源码学习分析

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

    LinkedList源码分析

    ### LinkedList源码分析 #### 一、概述 `LinkedList` 是 Java 集合框架中的一个重要组成部分,它基于双向链表实现。与基于数组的 `ArrayList` 相比,`LinkedList` 在插入和删除操作上更为高效,因为它只需要改变...

    linkedlist_链表_

    总结来说,"linkedlist_链表_"主题深入讲解了链表的基础概念,包括单链表和双链表的创建、节点的添加与删除、链表的逆序操作以及遍历技巧。掌握这些知识对于理解和应用数据结构,尤其是处理动态数据集合,具有重要...

    JAVA利用LinkedList构造栈与队列

    总结来说,LinkedList是Java中一个灵活且功能丰富的数据结构,通过合理利用其方法,我们可以构建出栈和队列,满足不同场景下的需求。不过,在追求性能时,应考虑使用专门为此设计的类。在阅读和分析给定的Queue.java...

    Jdk1.6 Collections Framework源码解析(2)-LinkedList

    《Jdk1.6 Collections Framework源码解析(2)-LinkedList》 LinkedList是Java集合框架中的一个重要的类,它是List接口的实现,同时继承了AbstractSequentialList,并实现了Deque接口。LinkedList是一种双链表结构,...

    深入arraylist,linkedlist,hashmap,hashset源码(2012/3/18)

    总结来说,深入理解ArrayList、LinkedList、HashMap和HashSet的源码,有助于我们更好地利用它们的特性,优化代码性能,并在面临并发问题时做出正确的选择。对于开发人员来说,掌握这些基础数据结构的实现原理是提高...

    LinkedList 所有公有方法和属性 导图

    .NET框架中的LinkList,实现的是双向链表,总结下它的实现源码。 LinkedList提供的公有属性和方法的导图

    毕向东Java基础源码+总结

    本资源“毕向东Java基础源码+总结”提供了一套全面的Java基础知识的源代码示例,帮助初学者深入理解Java的核心概念。 1. **基本语法与数据类型** Java提供了八种基本数据类型:byte, short, int, long, float, ...

    【死磕Java集合】-集合源码分析.pdf

    一、LinkedList源码分析 LinkedList是一种以双向链表实现的List,它除了作为List使用,还可以作为队列或者栈来使用。它实现了List、Queue和Deque接口,使其具有多种使用场景。 LinkedList的继承体系中,它继承了...

    javalist源码-Visualized_linked_List:在此存储库中包含链接列表源代码(java)由Eclipse开发

    总结来说,`javalist源码-Visualized_linked_List`项目提供了一个学习链表实现的平台,包括链表的增删改查操作及其可视化展示。通过研究该项目,开发者不仅可以深入理解链表的内部机制,还能了解到如何在Java中实现...

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

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

    Java相关技术总结,包括redis,MySQL,RabbitMq,面试题总结,源码解读

    阅读ArrayList和LinkedList的源码,有助于我们选择合适的数据结构以优化遍历和插入操作;分析LinkedList的迭代器实现,可以帮助我们了解并发修改异常(ConcurrentModificationException)的原因。 总之,Java开发者...

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

    项目相关 项目介绍 ...LinkedList 核心源码分析 HashMap 核心源码+底层数据结构分析 ConcurrentHashMap 核心源码+底层数据结构分析 LinkedHashMap 核心源码分析 CopyOnWriteArrayList 核心源码分析

    LinkedList.pdf

    LinkedList类在Java中实现了List接口,提供了链表的实现,根据文件内容,我们可以总结出以下几个关键知识点: 1. LinkedList内部通过维护两个指针first和last来分别指向链表的第一个节点和最后一个节点。当链表为...

    java软件技术文档-深入java8的集合2:LinkedList的实现原理.pdf

    总结来说,LinkedList是Java集合框架中的一个重要组成部分,它的核心优势在于高效的头部和尾部操作,但对中间元素的访问则相对较低效。理解其内部结构和实现原理对于优化代码性能和解决并发问题至关重要。在实际开发...

    Java源码阅读的真实体会.pdf

    六、 阅读源码的经验总结 * 阅读源码需要技术基础、强烈的求知欲和耐心。 * 阅读源码可以帮助开发者更好地理解项目中部署和配置相关的核心类开发。 * 阅读源码可以帮助开发者更好地理解 Web 框架的实现。 七、 ...

    JAVA源码学习的基本

    例如,深入研究`ArrayList`和`LinkedList`的区别,可以让我们明白这两种数据结构在内存分配、插入删除操作上的性能差异,从而在实际编程中做出更合适的选择。 其次,源码阅读能够帮助我们理解设计模式。Java中的...

    线性表实现源码-java

    总结,"线性表实现源码-java"涉及到Java中对线性表两种常见存储结构——顺序存储(ArrayList)和链式存储(LinkedList)的实现,以及相关的基本操作。这些源码对于学习和理解数据结构及其在Java中的应用具有重要意义...

    《C#从入门到精通》示例源码

    5. **集合与泛型**:ArrayList、LinkedList、HashSet、Dictionary等集合类提供数据存储和操作,而泛型则能确保集合中元素的数据类型安全。 6. **LINQ(Language Integrated Query)**:C#的查询表达式,用于从各种...

    数据结构马踏棋盘JAVA实验源码

    总结来说,“数据结构马踏棋盘JAVA实验源码”是一个结合了数据结构、算法和GUI编程的综合实践项目。它涵盖了二维数组、图遍历(DFS和BFS)、状态标记、队列和栈、递归、以及图形界面设计等多个核心编程概念,是学习...

Global site tag (gtag.js) - Google Analytics