Collection 集合源码剖析(上)

简介: Collection 集合源码剖析(上)

java_collections_overview.png

Collection



ArrayList源码剖析


添加元素分析


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);
    }
}
/**
     * Constructs an empty list with an initial capacity of ten.
     */
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
//将另一个数组直接全部赋值给新的数组,然后初始化
public ArrayList(Collection<? extends E> c) {
    elementData = c.toArray();
    if ((size = elementData.length) != 0) {
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    } else {
        // replace with empty array.
        this.elementData = EMPTY_ELEMENTDATA;
    }
}


add方法


他不仅可以实现添加,也可以实现插入操作


public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    /**
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
    public void add(int index, E element) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

以及对应的addAll方法,也可以是实现插入操作


public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }
    /**
     * Inserts all of the elements in the specified collection into this
     * list, starting at the specified position.  Shifts the element
     * currently at that position (if any) and any subsequent elements to
     * the right (increases their indices).  The new elements will appear
     * in the list in the order that they are returned by the
     * specified collection's iterator.
     *
     * @param index index at which to insert the first element from the
     *              specified collection
     * @param c collection containing elements to be added to this list
     * @return <tt>true</tt> if this list changed as a result of the call
     * @throws IndexOutOfBoundsException {@inheritDoc}
     * @throws NullPointerException if the specified collection is null
     */
    public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // Increments modCount
        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }


Set方法


对于set方法,就像源码中提及的那样,如果判断索引位置数组下标没有越界,那么就直接赋值即可


public E set(int index, E element) {
    rangeCheck(index);//下标越界检查
    E oldValue = elementData(index);
    elementData[index] = element;//赋值到指定位置,复制的仅仅是引用
    return oldValue;
}


get方法


获取数据索引位置数据,检查是否越界。如果没有,然后返回即可


public E get(int index) {
    rangeCheck(index);
    return (E) elementData[index];//注意类型转换
}


remove方法


传入要删除位置的索引,然后将索引位置后面的元素全部向前挪一位即可(赋值拷贝)


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; //清除该位置的引用,让GC起作用
    return oldValue;
}


trimToSize()方法

作用 : 将底层数组的容量调整为当前列表保存的实际元素的大小的功能。 ,以减少内存的开销


/**
     * Trims the capacity of this <tt>ArrayList</tt> instance to be the
     * list's current size.  An application can use this operation to minimize
     * the storage of an <tt>ArrayList</tt> instance.
     */
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
            ? EMPTY_ELEMENTDATA
            : Arrays.copyOf(elementData, size);
    }
}

indexOf()—获取元素第一次出现的位置


/**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     */
    public int indexOf(Object o) {
        //因为List可以存储null对象,所以源码地方在这里将其考虑进去,分开进行索引
        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;
    }


lastIndexOf() — 获取元素最后一次出现的位置


从最后开始索引,然后出现的第一个就是最后一个。源码牛

/**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     */
    public int indexOf(Object o) {
        //因为List可以存储null对象,所以源码地方在这里将其考虑进去,分开进行索引
        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;
    }


目录
相关文章
|
7月前
|
算法 安全 索引
【面试小知识】Collection(接口)集合
【面试小知识】Collection(接口)集合
|
Java
java集合框架Set子接口之HashSet源码剖析
HashSet类实现了由哈希表(实际上是HashMap实例)支持的Set接口 , 底层采用HashMap来保存的数据 , 存在HashSet中的元素是无序且不重复的并且HashSet是线程不安全的 , 这种不重复其实是由HashMap实现的 , 所以HashSet的实现也是相对比较简单的 , 对于它的操作其实都是调用HashMap的方法来实现的
70 2
|
6月前
(Collection)集合遍历,进阶
(Collection)集合遍历,进阶
|
7月前
|
存储 Java 索引
集合进阶Collection集合
这篇文档介绍了Java中的Collection集合和其子类List与Set的基本概念和特性。
61 3
|
存储 Java
Java集合Collection
Java集合Collection
68 0
|
Java 索引 容器
Collection 集合源码剖析(下)
Collection 集合源码剖析(下)
48 0
|
Java
Java集合-Collection
Java集合-Collection
147 1
Java集合-Collection
|
存储 Java
Java集合Collection类
数组在存储多个数据方面的缺点: 一旦初始化后,其长度就确定了 数组中提供的方法非常有限,对于添加、删除、插入数据等操作非常不便,同时效率不高。 获取数组中实际元素个数的需求,数组没有现成的属性或方法可用。 数组存储数据的特点:有序、可重复。对于无序、不可重复的需求不能满足。
79 0
|
存储 Java API
Java集合学习1:Collection集合、List(一)
概念:对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能。
Java集合学习1:Collection集合、List(一)
|
安全 Java 容器
Java集合学习1:Collection集合、List(二)
概念:对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能。
Java集合学习1:Collection集合、List(二)
下一篇
DataWorks