zoukankan      html  css  js  c++  java
  • JDK8集合类源码解析

    linkedList主要要注意以下几点:

    1构造器

    2 添加add(E e)

    3 获取get(int index)

    4 删除 remove(E e)remove(int index)

    5  判断对象是否存在:contain(E e) 

       Jdk8中的linkedList基于双向链表来实现的

    双向链表每个结点包含数据域,一个前指针和一个后指针,分别指向前驱结点和后继结点(如果有前驱/后继的话,没有就是null)。

    另外,双向链表还有一个first指针,指向头节点,和last指针,指向尾节点。

    接下来我们来看看源码

    transient int size = 0;

    transient Node<E> first; //整个链表的头结点

    transient Node<E> last; //整个链表的尾结点

    Node的数据结构如下
    private static class Node<E> {
        E item; 
        Node<E> next; //前驱
        Node<E> prev; //后继
    
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    

     如图所示

    1构造器

       有两个构造器,分别是空的和从一个集合创建。

     

      注意:因为基于链表创建,理论上无容量的限制,不需要扩容的操作。

    2 添加add(E e)

      默认添加是在链表尾部添加

      

     public boolean add(E e) {
            linkLast(e);
            return true;
        }
    void linkLast(E e) {
            final Node<E> l = last;
    //创建一个新结点 并且把尾结点设为当前结点的前驱
            final Node<E> newNode = new Node<>(l, e, null);
            last = newNode;
            if (l == null)//如果整个链表为空
                first = newNode; //把当前结点设为头结点
            else //不为空
                l.next = newNode; //把当前结点设为尾结点的后继
            size++;
            modCount++;
        }
    

      

    3 获取get(int index)

    public E get(int index) {
            checkElementIndex(index);
            return node(index).item;
        }
      Node<E> node(int index) {
            // assert isElementIndex(index);
    
            if (index < (size >> 1)) { //判断下标位置是在前半截还是后半截  如果在前半截
                Node<E> x = first;
                for (int i = 0; i < index; i++)
                    x = x.next; //从前往后找
                return x;
            } else {  //如果在后半截
    
                Node<E> x = last;
                for (int i = size - 1; i > index; i--)
                    x = x.prev;// 从后往前找
                return x;
            }
        }
      注意:1跟arraylist不同的是,linkedlist查找指定下标元素需要遍历 
            2  >> 1 (除以2)  <<1 (乘以2)
    

      

    4 删除 remove(E e)remove(int index)

     public boolean remove(Object o) {
            if (o == null) {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (x.item == null) { //先溢出第一个null
                        unlink(x);
                        return true;
                    }
                }
            } else {
                for (Node<E> x = first; x != null; x = x.next) {
                    if (o.equals(x.item)) { //找到了就移除
                        unlink(x);
                        return true;
                    }
                }
            }
            return false;
        }
    
    E unlink(Node<E> x) {
            // assert x != null;
            final E element = x.item;
            final Node<E> next = x.next; //当前元素的后继
            final Node<E> prev = x.prev;//当前元素的前驱
    
            if (prev == null) { //当前元素是头结点
                first = next;
            } else {
                prev.next = next; //设置当前元素的后继为前驱的后继
                x.prev = null;
            }
    
            if (next == null) { //当前元素是尾结点
                last = prev;
            } else {
                next.prev = prev;//设置当前元素的前驱为后继的前驱
                x.next = null;
            }
    
            x.item = null; //清空当前元素
            size--;
            modCount++;
            return element;
        }
    

      

    5  判断对象是否存在:contain(E e) 

     public boolean contains(Object o) {
            return indexOf(o) != -1;
        }
        public int indexOf(Object o) {
            int index = 0;
            if (o == null) {
              //从头开始找 找到第一个null
                for (Node<E> x = first; x != null; x = x.next) {
                    if (x.item == null)
                        return index;
                    index++;
                }
            } else {
              //从头开始找 看有没有等于item的
                for (Node<E> x = first; x != null; x = x.next) {
                    if (o.equals(x.item))
                        return index;
                    index++;
                }
            }
            return -1;
        }
    

      

    总结:1 Jdk8中的linkedList基于双向链表来实现的,插入删除快,查询慢,适合读少写多的情况

        2 linkedList还有一些有趣的方法,可以实现队列

        3添加元素时不用扩容

        4 线程不安全

  • 相关阅读:
    extjs tabpanel动态添加panel
    日期处理工具类
    POI导入导出Excel
    生成流水号
    计划排产系统
    3Dflash 图表xml数据封装
    使用GZIP动态压缩Extjs
    码农行业的薪水一览,如有雷同纯属巧合
    我的技术从今天开始开通啦~~~
    关于腾讯QQ
  • 原文地址:https://www.cnblogs.com/javabigdata/p/7091050.html
Copyright © 2011-2022 走看看