ArrayList 和 LinkedList

1. ArrayList 的实现

        ArrayList 底层数据结构:数组

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
transient Object[] elementData;  // 存储ArrayList元素的数组缓冲区

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};  // 用于默认大小的空实例的共享空数组实例

private int size;  // ArrayList的大小(包含的元素数)

private static final int DEFAULT_CAPACITY = 10;  // 默认初始容量

protected transient int modCount = 0;  // 此列表在结构上被<i>修改的次数</i>

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;  // 要分配的数组的最大大小

ArrayList 扩容机制

1)代码分析

① add 方法

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return <tt>true</tt> (as specified by {@link Collection#add})
 */
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // 确认 List 容量,如果不够,容量加 1。注意:只加 1,保证资源不被浪费 
    elementData[size++] = e;
    return true;
}

② ensureCapacityInternal 方法 

private void ensureCapacityInternal(int minCapacity) {
    // 判断 ArrayList 是否初始化
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}

        唯有调用 ArrayList 的无参构造方法才会满足

        elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 这个条件。

        有参构造方法可以在创建对象时为其进行一些初始化操作,如对类的字段进行赋值等。而无参构造则不需要进行任何初始化操作。

        故调用 ArrayList 的无参构造方法等同于 ArrayList 未初始化,

        elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA 等同于判断 ArrayList 是否初始化

        若 ArrayList 未初始化,则 minCapacity = 10

③ ensureExplicitCapacity 方法

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

        比较 elementData.length(存储 ArrayList 元素的数组缓冲区长度 || 数组长度)与 minCapacity(最小容量 || 新增数据元素的数组下标 index )的大小,若大于,则插入新增元素;反之,则扩容

④ grow 方法 - 扩容

/**
 * Increases the capacity to ensure that it can hold at least the
 * number of elements specified by the minimum capacity argument.
 *
 * @param minCapacity the desired minimum capacity
 */
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);
}

        若 elementData.length * 1.5(1.5 * length)<  minCapacity(index)则将 minCapacity 设置为数组的容量;反之则将 Integer.MAX_VALUE 设置为数组的容量

        将旧数组中的数据拷贝到新数组中

         插入新增元素

 2)文字叙述

第一步,确认 List 容量,如果不够,容量加 1

第二步,判断 ArrayList 是否初始化,若否,设置最小容量为 10;

第三步,判断数组长度是否大于新增数据元素的数组下标,若是,则插入新增元素【流程结束】;反之,扩充

第四步,判断 1.5 倍数组长度是否小于新增数据元素的数组下标,若是,则将最小容量(size + 1)为数组的容量;反之,则将 Integer.MAX_VALUE 设置为数组的容量

第五步,将旧数组中的数据拷贝到新数组中

第六步,插入新增元素【流程结束】

2. LinkedList 的实现

        LinkedList 底层数据结构:链表(双向链表)

3. ArrayList 和 LinkedList 的区别 

ArrayListLinkedList
底层数据结构数组链表(双向链表)
查询操作×
增删操作×
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值