OpenJDK8 List接口相关

本文详细探讨了OpenJDK8中List接口的三个主要实现类ArrayList、LinkedList和Vector。分析了它们的数据结构,如ArrayList使用数组,LinkedList使用双向链表,Vector同样基于数组。讨论了扩容机制,ArrayList和Vector在添加元素时会先扩容再插入,而LinkedList不涉及此类操作。同时,文章还提供了部分源码分析,并对比了三者的主要属性。
摘要由CSDN通过智能技术生成

今天,主要看了下List接口及其实现类,整体的类结构图如下。
在这里插入图片描述
主要的几个实现类为ArrayList, LinkedList, Vector,下面分别进行介绍。

1. ArrayList

1.1 数据结构

数组

1.2 扩容机制

先扩容再插值
当添加元素时,执行ensureCapacityInternal(int minCapacity)方法执行扩容逻辑,具体源码如下:

   /**
     * 在列表末尾追加元素
     */
    public boolean add(E e) {
   
        // 执行扩容逻辑
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        // 添加元素
        elementData[size++] = e;
        return true;
    }

    /**
     * 在索引位index上插入元素,后面元素随之后移一位
     */
    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++;
    }

实际扩容逻辑grow(int minCapacity)

/**
     * 扩容
     * 如果旧容量*1.5<minCapacity,以minCapacity容量为准;否则,设置1.5*旧容量
     */
    private void grow(int minCapacity) {
   
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

ArrayList对外提供了ensureCapacity,可以由用户显式调用,当发生大量元素添加时,可以一次性分配足量的空间,避免数组多次扩容开销。

1.3 源码


/**
 * 可变数组实现
 * 除了非线程安全,与Vector类似
 * O(1)方法 size/isEmpty/get/set/iterator/listIterator
 * ≈O(1)方法 add
 * ensureCapacity可以在批量添加大量元素前,对数组容量进行扩容,可以减少重复扩容的次数
 * @see     Collection
 * @see     List
 * @see     LinkedList
 * @see     Vector
 * @since   1.2
 */

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
   
    /**
     * 默认初始化数组容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 公用的空数组实例
     */
    private static final Object[] EMPTY_ELEMENTDATA = {
   };

    /**
     * 公用的默认容量空实例,第一个元素添加时,自动扩容到默认大小10
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {
   };

    /**
     * 底层的数组存储buffer
     */
    transient Object[] elementData; // non-private to simplify nested class access

    private int size;

    /**
     * 构造一个指定容量的数组列表
     */
    public ArrayList(int initialCapacity)
    /**
     * 构造一个空的默认容量列表
     */
    public ArrayList()
    /**
     * 构建包含给定集合c中所有元素的列表,列表元素保持了集合迭代顺序
     */
    public ArrayList(Collection<? extends E> c)
    
    /**
     * 将列表容量与当前实际元素个数设置一致,可以最小化存储空间
     */
    public void trimToSize()
    
    /**
     * 扩容,在批量添加元素时先显式调用该方法可以减少系统重复扩容分配空间的开销
     */
    public void ensureCapacity(int minCapacity)
    private void ensureCapacityInternal(int minCapacity)
    private void ensureExplicitCapacity(int minCapacity)

    /**
     * 数组的最大容量
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * 扩容
     * 如果旧容量*1.5<minCapacity,以minCapacity容量为准;否则,设置1.5*旧容量
     */
    private void grow(int minCapacity) {
   
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
    public int size()
    public boolean isEmpty()
    public boolean contains(Object o)

    /**
     * 返回元素第一次出现的索引
     * 不存在,返回-1
     */
    public int indexOf(Object o)

    /**
     * 返回元素最后一次出现的索引
     * 不存在,返回-1
     */
    public int lastIndexOf(Object o)

    public Object clone()
    public Object[] toArray()
    public <T> T[] toArray(T[] a)

    // Positional Access Operations
    E elementData(int index)
    /**
     * 返回列表指定索引位置的元素
     */
    public E get(int index) 
    /**
     * 用给定的元素替代列表某个索引位上的元素
     */
    public E set(int index
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值