JAVA集合之List源码阅读

1. ArrayList

1.1 初始化

	初始化有三种方式,不传值、传int、传Collection
  1. List<Integer> list = new ArrayList<Integer>();
	/**
     * 使用默认的空数组,扩容将发生在第一次添加元素
     */
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
  1. List<Integer> list = new ArrayList<Integer>(20);
	/**
     * 根据传入的参数为初始容量赋值,如果参数为负数会抛出异常,如果参数为0会使用默认的空数组
     * 可以看出,ArrayList底层还是一个数组
     */
    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);
        }
    }
  1. List<Father> list = new ArrayList<Father>(sons);
	/**
     * 传入一个以类型E或其子类的对象的Collection,Collection可以是List或Set的子类
     * 首先调用c的toArray()函数转化为数组,赋值给ArrayList里的数组
     * 判断语句if (elementData.getClass() != Object[].class)
     * 解释参考[https://blog.csdn.net/weixin_39452731/article/details/100189934]
     */
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] 
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

1.2 赋值

list.add(1);
	/**
     * 此时已经int类型参数转化为Integer类型
     * 添加元素时,如果当前**需要**的数组大小(size + 1)比当前数组大小(elementData.length)大,
     * 将会对数组进行扩容。
     * 扩容完成后再赋值
     */
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
	/**
     * 扩容:首先扩容至旧容量的1.5倍,如果此时还是达不到minCapacity的要求,会将容量设置为minCapacity。
     * 如果新容量超过了MAX_ARRAY_SIZE(Integer.MAX_VALUE - 8),此时,如果minCapacity也大于
     * MAX_ARRAY_SIZE会报错,否则设置为MAX_ARRAY_SIZE。最后用Arrays.copyOf将旧数据拷贝到
     * 新的内存空间,完成扩容
     * @param minCapacity the desired minimum capacity
     * minCapacity在数组为空时为默认值或初始化时设定的值,数组非空时为size + 1,
     * size指当前数组的长度
     */
    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);
    }

1.3 contains()

list.contains(1)
	/**
     * 返回true/false,实际上利用的是indexOf()来查找元素在ArrayList中的下标
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
    /**
     * 由于ArrayList可以存储null,因此要对检查的元素判断是否为null
     */
    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

1.4 remove()

list.remove(1);
	/**
     * 删除指定位置的元素,返回被删除的元素
     * 
     * 首先检查index是否在范围中,然后从index+1位置开始的元素左移,并释放最后一个位置的内存
     */
    public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

2. LinkedList

2.1 初始化

1.List<Integer> list = new LinkedList<Integer>();

	/**
     * 只初始化了成员变量
     */
public LinkedList() {
    }

2.List<Integer> list = new LinkedList<Integer>(list2);

/**
     * 按照Collection的顺序添加元素,并记录好头元素和尾元素
     */
public LinkedList(Collection<? extends E> c) {
        this();
        addAll(c);
    }
public boolean addAll(Collection<? extends E> c) {
        return addAll(size, c);
    }
public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);

        Object[] a = c.toArray();
        int numNew = a.length;
        if (numNew == 0)
            return false;

        Node<E> pred, succ;
        if (index == size) {
            succ = null;
            pred = last;
        } else {
            succ = node(index);
            pred = succ.prev;
        }

        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
            Node<E> newNode = new Node<>(pred, e, null);
            if (pred == null)
                first = newNode;
            else
                pred.next = newNode;
            pred = newNode;
        }

        if (succ == null) {
            last = pred;
        } else {
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;
        modCount++;
        return true;
    }

2.2 赋值

list.add(1);
/**
     * 链接到尾部 返回true
     */
    public boolean add(E e) {
        linkLast(e);
        return true;
    }

/**
     * Links e as last element.
     */
    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++;
    }

2.4 contains

	/**
     * indexOf返回对象的下标
     */
public boolean contains(Object o) {
        return indexOf(o) != -1;
    }
	/**
     * 逻辑和ArrayList大致相同
     */
public int indexOf(Object o) {
        int index = 0;
        if (o == null) {
            for (Node<E> x = first; x != null; x = x.next) {
                if (x.item == null)
                    return index;
                index++;
            }
        } else {
            for (Node<E> x = first; x != null; x = x.next) {
                if (o.equals(x.item))
                    return index;
                index++;
            }
        }
        return -1;
    }

2.4 删除

list.remove(1);
/**
     * 
     */
public E remove(int index) {
        checkElementIndex(index);
        return unlink(node(index));
    }
    /**
     * 找到下标为index的元素,如果index小于size/2,则从头找;反之,从尾巴逆着找、
     * 返回index代表的元素
     */
Node<E> node(int index) {
     // assert isElementIndex(index);

     if (index < (size >> 1)) {
         Node<E> x = first;
         for (int i = 0; i < index; i++)
             x = x.next;
         return x;
     } else {
         Node<E> x = last;
         for (int i = size - 1; i > index; i--)
             x = x.prev;
         return x;
     }
 }
  /**
     * 利用x的pre和next从链表中断开x
     */
    E unlink(Node<E> x) {
        // assert x != null;
        final E element = x.item;
        final Node<E> next = x.next;
        final Node<E> prev = x.prev;

        if (prev == null) {
            first = next;
        } else {
            prev.next = next;
            x.prev = null;
        }

        if (next == null) {
            last = prev;
        } else {
            next.prev = prev;
            x.next = null;
        }

        x.item = null;
        size--;
        modCount++;
        return element;
    }

3. Vector

3.1 初始化

List<Integer> list = new Vector<Integer>();
/**
     * 构造一个空的数组,默认大小为10
     */
    public Vector() {
        this(10);
    }
    /**
     * this()构造函数会接着调用this(initialCapacity,capacityIncrement),初始化大小以及增长
     * 的幅度
     */
    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

带参数的构造方式实际上也是调用第二个函数

3.2 其他

其他操作和ArrayList是一样的,在扩容上,如果没有设定capacityIncrement的值,则默认为0,同时,扩容时会2倍容量扩容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值