Java集合框架

来源:互联网 发布:电脑怎么下载不了淘宝 编辑:程序博客网 时间:2024/05/18 00:48

首先要知道,LinkedList实现的是双向循环链表。

链表的组成元素我们称之为节点,节点由三部分组成:前一个节点的引用地址、数据、后一个节点的引用地址。LinkedList的Head节点不包含数据,每一个节点对应一个Entry对象。下面我们通过源码来分析LinkedList的实现原理。

     1、Node类源码:

复制代码
 1 private static class Node { 2     Object item; 3     Node next; 4     Node prev; 5  6     Node(Node Node1,Object obj, Node Node2) { 7         item = obj; 8         this.next = node2; 9         this.prev = node1;10     }11     }
复制代码

     Node类包含三个属性,其中item存对象数据;next存放后一个节点的信息,通过next可以找到后一个节点;prev存放前一个节点的信息,通过previous可以找到前一个节点。

     2、LinkedList的构造方法:LinkedList提供了两个带不同参数的构造方法。

     1) LinkedList(),构造一个空列表。

     2) LinkedList(Collection<? extends E> c),构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列。

     

复制代码
 1 private transient Node header = new Node(null, null, null); //声明一个空的Entry对象 2 private transient int size = 0; //集合中节点的个数 3  4 public LinkedList() { 5    size = 0;  //只设置size = 0 6 } 7  8 public LinkedList(Collection<? extends E> c) { 9    this(); //调用不带参数的构造方法,创建一个空的循环链表10    addAll(c); //调用addAll方法将Collection的元素添加到LinkedList中11 }
复制代码

                                                      

      当调用带集合参数的构造方法生成LinkedList对象时,会先调用不带参数的构造方法创建一个空的循环链表,然后调用addAll方法将集合元素添加到LinkedList中。
 

      3、向集合中添加元素:LinkedList提供了多种不同的add方法向集合添加元素。

      1) add(E e),将指定元素添加到此列表的结尾。

      2) add(int index, E element),在此列表中指定的位置插入指定的元素。

      3) addAll(Collection<? extends E> c),添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。

      4) addAll(int index, Collection<? extends E> c),将指定 collection 中的所有元素从指定位置开始插入此列表。

      5) addFirst(E e),将指定元素插入此列表的开头。

      6) addLast(E e),将指定元素添加到此列表的结尾。 

      通过源码来分析其底层的实现原理:  

      

复制代码
 1 public boolean add(Object obj) { 2     linkLast(obj);   3     return true; 4 } 5 private void linkFirst(Object obj)    {        Node node1 = first;        Node node2 = new Node(null, obj, node1);        first = node2;        if(node1 == null)            last = node2;        else            node1.prev = node2;        size++;        modCount++;    }   void linkLast(Object obj)    {        Node node1 = last;//初始化的时候last为null        Node node2 = new Node(node1, obj, null);    //刚开始的时候直接添加obj        last = node2;   //把第一个放进来的存obj的Node设为last         if(node1 == null)            first = node2;//把第一个Node设为first        else            node1.next = node2;        size++;        modCount++;    }
复制代码

     这个过程很简单,基本的数据结构

    add 另一个方法和addAll()方法

1 public void add(int i, Object obj) {2       checkPositionIndex(i);        if(i == size)            linkLast(obj);        else            linkBefore(obj, node(i));3 }
//判断是否index越界也就是size小于i
 private void checkPositionIndex(int i)    {        if(!isPositionIndex(i))            throw new IndexOutOfBoundsException(outOfBoundsMsg(i));        else            return;    }
private boolean isPositionIndex(int i)    {        return i >= 0 && i <= size;    }
//查找要插入的Node节点
 Node node(int i)    {        if(i < size >> 1)        {            Node node1 = first;            for(int j = 0; j < i; j++)                node1 = node1.next;            return node1;        }        Node node2 = last;        for(int k = size - 1; k > i; k--)            node2 = node2.prev;        return node2;    }
//在Node1之前插入
void linkBefore(Object obj, Node node1)    {        Node node2 = node1.prev;        Node node3 = new Node(node2, obj, node1);  //创建一个Node3 前驱为Node2,后为Node1        node1.prev = node3;        if(node2 == null)            first = node3;        else            node2.next = node3;        size++;        modCount++;    }
复制代码
 1 public boolean addAll(Collection<? extends E> c) {
 2         return addAll(size, c); 3 } 4  5 public boolean addAll(int index, Collection<? extends E> c) { 6         checkPositionIndex(i); 9         Object aobj[] = collection.toArray();        int j = aobj.length;        if(j == 0)            return false;        Node node1;  //保存前驱和后继节点        Node node2;
//判断是在尾部还是中间和前面插入 个人觉得有点多余  因为是在size后面添加        if(i == size)        {            node2 = null;            node1 = last;        } else        {            node2 = node(i);            node1 = node2.prev;        }        Object aobj1[] = aobj;        int k = aobj1.length;        for(int l = 0; l < k; l++)        {            Object obj = aobj1[l];            Object obj1 = obj;            Node node3 = new Node(node1, obj1, null);            if(node1 == null)                first = node3;            else                node1.next = node3;            node1 = node3;        }        if(node2 == null)        {            last = node1;        } else        {            node1.next = node2;            node2.prev = node1;        }        size += j;        modCount++;        return true;26     }
复制代码

     4、获取LinkedList中的元素:

    get方法更简单,先检查是否越界,然后直接Node(int i).Item就可以得到了。

     5、移除LinkedList中的元素:

     1) remove(int index),移除此列表中指定位置处的元素。

     2) remove(Object o),从此列表中移除首次出现的指定元素(如果存在)。