ArrayList的基本实现

1、通过Object类型的数组来实现,所以数组中需要存储基本类型数据的时候需要使用包装类

public class ArrayList<E> extends AbstractList<E>

        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

{

    private static final long serialVersionUID = 8683452581122892189L;

 

    /**

     * Default initial capacity.

     */

    private static final int DEFAULT_CAPACITY = 10;

 

    /**

     * Shared empty array instance used for empty instances.

     */

    private static final Object[] EMPTY_ELEMENTDATA = {};

 

    /**

     * Shared empty array instance used for default sized empty instances. We

     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when

     * first element is added.

     */

    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

 

    /**

     * The array buffer into which the elements of the ArrayList are stored.

     * The capacity of the ArrayList is the length of this array buffer. Any

     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

     * will be expanded to DEFAULT_CAPACITY when the first element is added.

     */

    transient Object[] elementData; // non-private to simplify nested class access

2、初始化的无参构造函数为一个空对象数组,在添加第一个元素的时候,会默认申请10个大小的内存空间,如果添加到了尾端,在进行1.5倍的空间申请并将原来存储的数据挪动复制到新申请的内存空间中

/**

 * Constructs an empty list with an initial capacity of ten.

 */

public ArrayList() {

    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

}

/**

 * Increases the capacity to ensure that it can hold at least the

 * number of elements specified by the minimum capacity argument.

 *

 * @param minCapacity the desired minimum capacity

 */

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

}

3、数组在遍历的时候很快就是因为内存地址是连续的,所以查找某个位置的元素可以瞬间获取到,所以遍历的是特别快的,通过第一个元素的地址就能计算出后面第N位的元素地址

4、ArrayList实现了一个叫RandomAccess的空接口,实际上实现这个接口只是为了做打标,就是告诉别人当前的这个类支持快速访问,所以在进行泛型对象的遍历的时候,由于我们不清楚具体的实现类是什么,所以可以判断是否实现了RandomAccess接口,如果实现了此接口则进行for循环遍历集合,否之则使用迭代器,所以这里的RandomAccess就是为了告诉别人当前实现类支持快速访问,但实际上是否能快速访问还是因为存储的数据结构不一样

 

public static void loop(java.util.List list){

    if(list instanceof RandomAccess) {

        // for循环

        System.out.println("采用for循环遍历");

        for (int i = 0;i< list.size();i++) {

            System.out.println(list.get(i));

        }

    } else {

        // 迭代器

        System.out.println("采用迭代器遍历");

        Iterator it = list.iterator();

        while(it.hasNext()){

            System.out.println(it.next());

        }

    }

}

public static void main(String[] args) {

    java.util.List<String> list = Arrays.asList("123","456","789","1110");

    java.util.List<String> list1 = new LinkedList<>();

    list1.add("aaa");

    list1.add("bbb");

    list1.add("ccc");

    loop(list);

    loop(list1);

}

5、ArrayList中的存储数组elementData是用transient修饰的,而ArrayList又是实现了Serializable接口表明是可实例化的,这里就是很矛盾,因为被transient修饰的数据是不会被实例化的。实际上是因为刚刚说的数组的空间是必须要提前申请的,所以这里有个问题就是数组可能会空间比较大,但实际上存储的元素没有那么多。所以在序列化的时候完全不需要去序列化那些空内存,所以ArrayList手动实现了序列化方法,根据元素的多少进行序列化。

/**

 * The array buffer into which the elements of the ArrayList are stored.

 * The capacity of the ArrayList is the length of this array buffer. Any

 * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA

 * will be expanded to DEFAULT_CAPACITY when the first element is added.

 */

transient Object[] elementData; // non-private to simplify nested class access

/**

 * Save the state of the <tt>ArrayList</tt> instance to a stream (that

 * is, serialize it).

 *

 * @serialData The length of the array backing the <tt>ArrayList</tt>

 *             instance is emitted (int), followed by all of its elements

 *             (each an <tt>Object</tt>) in the proper order.

 */

private void writeObject(java.io.ObjectOutputStream s)

    throws java.io.IOException{

    // Write out element count, and any hidden stuff

    int expectedModCount = modCount;

    s.defaultWriteObject();

 

    // Write out size as capacity for behavioural compatibility with clone()

    s.writeInt(size);

 

    // Write out all elements in the proper order.

    for (int i=0; i<size; i++) {

        s.writeObject(elementData[i]);

    }

 

    if (modCount != expectedModCount) {

        throw new ConcurrentModificationException();

    }

}

/**

 * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,

 * deserialize it).

 */

private void readObject(java.io.ObjectInputStream s)

    throws java.io.IOException, ClassNotFoundException {

    elementData = EMPTY_ELEMENTDATA;

 

    // Read in size, and any hidden stuff

    s.defaultReadObject();

 

    // Read in capacity

    s.readInt(); // ignored

 

    if (size > 0) {

        // be like clone(), allocate array based upon size not capacity

        ensureCapacityInternal(size);

 

        Object[] a = elementData;

        // Read in all elements in the proper order.

        for (int i=0; i<size; i++) {

            a[i] = s.readObject();

        }

    }

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值