List接口

1. 集合概述

68747470733a2f2f67756964652d626c6f672d696d616765732e6f73732d636e2d7368656e7a68656e2e616c6979756e63732e636f6d2f736f757263652d636f64652f647562626f2f6a6176612d636f6c6c656374696f6e2d6869657261726368792e706e67

2. List接口的实现类的底层数据结构

ArrayList:Object[]数组

transient Object[] elementData;   // ArrayList实现数组

Vector:Object[]数组

protected Object[] elementData;   // Vector实现数组

LinkedList:双向链表

// LinkedList的结点内部类
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;
        }
    }

3. 集合介绍

ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。

VectorArrayList 一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写 Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问 ArrayList 慢。

LinkedList 是用链表结构存储数据的,很适合数据的动态插入和删除,随机访问和遍历速度比较慢。

4.ArrayList源码分析

4.1 构造器

List list = new ArrayList<>():将会调用空参构造器,初始化一个默认的空数组。

//  默认的空数组的成员变量
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// ArrayList空参构造器
public ArrayList() {
	this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

List list = new ArrayList<>(int length):将会调用有参构造器,初始化一个存储空间为length的数组

// 空的对象数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 有参构造器
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);
    }
}

4.2 add()方法:当使用空参构造器时,第一次插入元素时会初始化一个长度为10的数组。

public boolean add(E e) {
    // 扩容
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}
// 计算最小扩容容量
// 未超过数组的存储容量时,最小扩容容量 = 数组的存储容量
// 超过数组的存储容量时, 最小扩容容量 = size + 1
private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// 判断是否需要扩容
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        // 扩容
    	grow(minCapacity);
}
private void grow(int minCapacity) {
    // overflow-conscious code
    // oldCapacity:为数组的存储容量
    int oldCapacity = elementData.length;
    // newCapacity:为扩容的容量,即数组容量扩容1.5倍
    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);
}
posted @   Lyfzzz  阅读(67)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示