List集合

99 阅读2分钟

ArrayList

1. ArrayList 底层是由数组实现的int

2. ArrayList 线程不安全(执行效率高),在多线程的情况下不建议使用,而是使用Vector

3. 线程不安全主要体现在 ArrayList add() ->
当创建 ArrayList 无参构造器时 —> ArrayList()
ArrayList 底层维护了一个 Object类型的数组 elementData 容量为0
->  transient Object[] elementData;  // transient -> 表示该属性不会被序列化
第一次添加时,则会把 elementData 扩容为10 ,如果需要再次扩容,则扩容当前 elementData的1.5倍
当创建 ArrayList 有参构造器时 —> ArrayList(int)
ArrayList 则创建指定大小的容器 -> elementData 为指定大小 如果需要扩容,则扩容当前 elementData的1.54. 源码跟踪  -> 无参构造器创建 
new ArrayList<>().add();
-> this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; // 第一次创建初始化
这里的执行一个空数组 DEFAULTCAPACITY_EMPTY_ELEMENTDATA = private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
-> 执行add()
->  public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Capacity(容量) (先确认是否需要扩容)
    elementData[size++] = e;
    return true;
}

->  private void ensureCapacityInternal(int minCapacity) { // 第一次进来会传 ensureCapacityInternal(size + 1); -> 0 + 1
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // 进来先判断 elementData 是否为空数组
    minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // 如果是,获取最大值,初始化容量为 private static final int DEFAULT_CAPACITY = 10;
}
    ensureExplicitCapacity(minCapacity); // 此处判断是否需要扩容
}

private void ensureExplicitCapacity(int minCapacity) {
modCount++;  // 递增变量 modCount() 记录当前集合修改次数,防止多个线程同时修改
if (minCapacity - elementData.length > 0) {
    grow(minCapacity);
}

private void grow(int minCapacity) {
int oldCapacity = elementData.length; // 记录当前数组长度
int newCapacity = oldCapacity + (oldCapacity >> 1); // 原数组大小 + 原数组大小右移1位(原数组 / 2) -> 1.5倍
if (newCapacity - minCapacity < 0) { // 如果新数组长度 - 当前数组长度 小于0 则直接返回当前长度
    newCapacity = minCapacity;
}
if (newCapacity - MAX_ARRAY_SIZE > 0) {  // 如果新数组比最大容量还要大,执行新策略
    newCapacity = hugeCapacity(minCapacity);
}
elementData = Arrays.copyOf(elementData, newCapacity); // 返回一个新数组
}

private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) {
    throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE) ?
    Integer.MAX_VALUE :
    MAX_ARRAY_SIZE;
}

LinkedList

/*
    1. LinkedList 底层实现了双线链表和双端队列
    2. 可以添加任意元素 线程不安全
    3. LinkedList维护了两个属性 first 和 last 分别指向首节点和尾节点
    每个节点(Node对象) 里面又维护了prev next item 三个属性
    prev 指向前一个节点  next 指向后一个节点 最终实现双向链表

    add()

    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;
    }
    }

    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++;
    }
 */
/**
 * @Author LWL
 * @Date 2022/8/27 0:13
 * @TODO 模拟双向链表
 */
public class LinkedListTest {

    static class Node {

        private Object item;

        private Node next;

        private Node prev;

        public Node(Object item) {
            this.item = item;
        }

        public String ToString() {
            return "Node name = " + item;
        }
    }

    public static void main(String[] args) {

        Node varAble1 = new Node("VarAble1");
        Node varAble2 = new Node("VarAble2");
        Node varAble3 = new Node("VarAble3");

        varAble1.next = varAble2;  // 连接各个点
        varAble2.next = varAble3;
        varAble3.prev = varAble2;
        varAble2.prev = varAble1;

        Node first = varAble1; // 设置头节点
        Node last = varAble3; //  设置尾节点

        while (true) {
            if (ObjectUtil.isEmpty(first)) {
                break;
            }
            System.out.println("first = " + first.ToString());
            first = first.next;
        }

        Node varAble4 = new Node("VarAble4"); // 如需添加新元素,只需要创建新的 Node节点
        varAble4.next = varAble3; // 往中间插
        varAble4.prev = varAble2;
        varAble2.next = varAble4;
        varAble3.prev = varAble4;

        first = varAble1; // 初始化头节点
        while (true) {
            if (ObjectUtil.isEmpty(first)) {
                break;
            }
            System.out.println("first = " + first.ToString());
            first = first.next;
        }
    }

Vector

/*
  1. Vector 底层也是一个对象数组
  2. Vector 类的操作方法带有 synchronized ,所以该线程安全
  3. Vector 无参构造默认初始容量 10 ,当容量满后,按照两倍扩容

  public Vector() {
     this(10);
  }

  public Vector(int initialCapacity) {
    this(initialCapacity, 0);
  }

  public Vector(int initialCapacity, int capacityIncrement) {
    super();  ->  protected AbstractList() {}
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;  -> protected int capacityIncrement;
  }

  add()
  public synchronized boolean add(E e) {
    modCount++;
    ensureCapacityHelper(elementCount + 1);
    elementData[elementCount++] = e;
    return true;
  }

  private void ensureCapacityHelper(int minCapacity) {
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
  }

  private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}
 */