List源码分析

List源码分析

List

List 是继承Colection的接口 我们主要学习他的实现类 ArrayList 和 LinkedList

ArrayList

ArrayList是基于数组实现的 与数组不同的是 它可以存放不同的数据类型的数据而且长度不定

// 我们分析一下他的底程实现 
// 添加过程
public boolean add(E e) {// add方法就是我往里面添加元素
        ensureCapacityInternal(size + 1);  //确定内部容量 
        elementData[size++] = e;// 往数组里面添加元素e
        return true;//添加成功后返回true
    }

// 如何做到长度可变
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData; // 数据是Object类型的所以可以存放任意类型的数据
private static final int DEFAULT_CAPACITY = 10;
// 首先 他通过ensureCapacityInternal方法得到一个最小容量
// 如果我们创建了一个空ArrayList 那么他的默认容量就是10
private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
    //然后将得到的最小容量传到ensureExplicitCapacity方法中
        ensureExplicitCapacity(minCapacity);
    }
// 
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // 如果我们最小长度大于elementData的长度就增长 也就是执行grow(minCapacity)
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
    // 这段代码的意思就是 给个新长度 重新创建一个数组 将原来的数组拷贝到新数组
	//  获取原来数组的长度 
    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);
    }

LinkedList

LinkedList 是基于链表实现的 也是可以存储不同类型的数据 长度不定

具体实现过程是创建一个Node类 类中有三个字段 一个保存我们要存入的数据 一个保存链表前一个对象的地址值 一个保存下一个对象的地址值 Node源码如下

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

//  添加过程 我们调用add添加的时候是直接调用的linkLast(e) 末尾添加
public boolean add(E e) {
        linkLast(e);
        return true;
    }
// 末尾添加 
 void linkLast(E e) {
        final Node<E> l = last;// l是我们没放入数据是的最后一个对象
        final Node<E> newNode = new Node<>(l, e, null);// 创建一个新Node对象
        last = newNode;
        if (l == null) // 如果l不存在 那么我们创建的对象就是第一个
            first = newNode;
        else           // 如果存在就把我们新创建的对象的地址值给上一个对象 就形成了链表
            l.next = newNode;
        size++;
        modCount++;
    }

猜你喜欢

转载自blog.csdn.net/qq_29991091/article/details/89788246
今日推荐