zoukankan      html  css  js  c++  java
  • ArrayList类源码浅析(一)

    1、首先来看一下ArrayList类中的字段

    可以看出,ArrayList维护了一个Object数组,默认容量是10,size记录数组的长度;

    2、ArrayList提供了三个构造器:ArrayList(int initialCapacity),ArrayList(),ArrayList(Collection<? extends E> c)

    带int参数的构造是指定ArrayList的大小,无参的构造函数,Object[]初始化为一个空数组,重点来讨论接受一个Colection参数的构造器,先看看源码

    传入的Collection对象得到一个数组,赋值给elementData,然后再判断是否是Object[]类型,如果不是,则在copyOf方法里面生成一个Object[]数组,

    返回并且赋值给elementData;Arrays.copyOf方法有多个重载方法,但是底层都是统一的调用System类中的arraycopy方法,这是一个系统的方法;

    3、get(int index)、set(int index, E element)、remove(int index)方法

    涉及到下标的操作,调用这三个方法,都会检查下标index是否合法,如果index>size,直接会抛出异常;

    这两个方法都会调用一个公用的方法elementData(index),是根据下标index获取数组中的元素;

    4、add(E e)、add(int index, E element)方法

    在调用这两个方法的时候,都会调用ensureCapacityInternal(size + 1),来进行数组的扩容操作;

    数组扩容分为两路:

      1、如果是调用无参的构造函数创建的ArrayList对象,那么是第一次扩容,第一次扩容的数组大小为 final int DEFAULT_CAPACITY = 10;

      2、如果ArrayList对象中数组已经存在,并且size+1超过了数组的长度,那么也需要进行数组的扩容;

      这时因为elementData数组中已经有值,扩容时,数组长度增加为扩容之前的1.5倍,把原来数组的数据复制到新的数组中去;

      这里就存在一个问题,如果频繁的去执行add操作,那么就会进行频繁的数组复制;

      如果数组有100万个元素,那么就是有大量的是、内存复制操作,对于GC的压力会比较大,同时这个操作的效率也会非常低;

      所以,必要的时候,可以指定数组的大小,使用ArrayList(int initialCapacity)构造方法去构造ArrayList对象,一定程度上能提高效率;

    5、remove(Object o)这个方法可以看一下

    这个方法是从ArrayList中删除一个元素,因为ArrayList里面可以存在null元素,所以在删除时,需要分开处理;

    如果o为空,执行一个条件块,如果不为空执行另外一个条件块;

    他们调用共用的删除方法:fastRemove(int index),这个方法在删除时,也是进行数组的复制;

  • 相关阅读:
    区块链服务平台设计
    Fabric 架构与设计
    ELSE 技术周刊(2017.12.25期)
    ELSE 技术周刊(2017.12.25期)
    ELSE 技术周刊(2017.12.25期)
    UDT的Sender和Receiver
    UDT的Sender和Receiver
    UDT的Sender和Receiver
    UDT的Sender和Receiver
    JavaScript 后台获取数据
  • 原文地址:https://www.cnblogs.com/lianliang/p/5757624.html
Copyright © 2011-2022 走看看