List接口常用实现类对比

时间:2021-07-22 17:06:49   收藏:0   阅读:1

相同点

都实现了List接口 储存了有序 可重复的数据

不同点

ArrayList

线程不安全 但是效率高 底层使用 Object[] elementData 实现

LinkedList

底层使用双向链表数据结构 对于频繁的插入 删除 该类比ArrayList效率高

Vector

线程安全 但是效率低 底层使用 Object[] elementData 实现

源码分析

ArrayList

JDK8ArrayList底层使用Object[] elementData数组存储 默认初始化大小10

/**
     * Default initial capacity. 默认初始化容量 10
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * Shared empty array instance used for empty instances.
	 * 用于空实例的数组 即 new ArrayList(0)
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
	 * 用于默认大小的空实例的共享空数组实例
 	 * 将其与 EMPTY_ELEMENTDATA 区别开来,以便知道何时应该膨胀多少
	 * 添加第一个元素。
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 
    transient Object[] elementData; // non-private to simplify nested class access
   
    private int size; // 数组大小

构造函数

public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    public ArrayList(Collection<? extends E> c) {
        Object[] a = c.toArray();
        if ((size = a.length) != 0) {
            if (c.getClass() == ArrayList.class) {
                elementData = a;
            } else {
                elementData = Arrays.copyOf(a, size, Object[].class);
            }
        } else {
            // replace with empty array.
            elementData = EMPTY_ELEMENTDATA;
        }
    }

有三种构造函数 无参构造函数 有参构造函数(集合类型的构造函数 int类型的构造函数)
ArrayList list = new ArrayList(); 此时调用ArrayList无参构造函数 底层Object[] elementData初始化为{} 没有创建集合大小!!!!!


add方法

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

当实例ArrayList后 得到list对象 此时Object[] elementData初始化为{} 调用add方法时
此时容量才被初始化为 10
技术分享图片
因为elementData为 {} 长度为 0 没有达到最低容量要求 必须得扩容了
技术分享图片
技术分享图片



小结

  1. 只要集合长度没有达到最小容量 必须得扩容 长度一般是原来的1.5倍(位运算符 >>1 相当于 原来的容量 / 2 + 原来的容量)
  2. ArrayList对象创建类似于 单例模式的懒汉式 延迟了数组的创建 节省内存

LinkedList

LinkedList linkList = new LinkedList();
技术分享图片
linkList.add("wwbao");

public boolean add(E e) {
        linkLast(e); // 调用linkLast方法 并且将添加的值也传过去
        return true;
}

技术分享图片

示意图

技术分享图片

小结

  1. 双向链表中 第一个节点的prev永远为 null 最后一个节点的next 永远为null
  2. 上一个节点的next指向下一个节点 下一个节点的prev指向上一个节点

原文:https://www.cnblogs.com/juanbao/p/15039599.html

评论(0
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!