JDK源码学习01--java.util.list-01

List是继承Collection接口的一个子接口,其主要的实现有ArrayList、LinkedList和Vector

一、ArrayList:

1、主要变量、常量等基本定义

 int DEFAULT_CAPACITY  :默认的初始容量,ArrayList会定义一个默认的初始容量,初始值为10

Object[] EMPTY_ELEMENTDATA = {}:默认空对象:ArrayList中对象数量为空时默认为{}

Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}:按介绍来说,任何带有                        elementdata==defaultcapacity_empty_elementdata的ArrayList对象在调用Add之前都为EMPTY_ELEMENTDATA,也就是说如果新建一个空的ArrayList变量,则elementdata默认为该值

疑问:DEFAULTCAPACITY_EMPTY_ELEMENTDATA与EMPTY_ELEMENTDATA的区别在哪?当elementdata为EMPTY_ELEMENTDATA时是否还可以调用Add方法?

Object[] elementData:存储ArrayList对象

int size:ArrayList的长度

2、构造方法:

传入一个整型变量

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

初始化时传入一个整型变量,如果这个变量大于零,会将elementData的长度设置为该整型变量,如果为0,则设置为空,即EMPTY_ELEMENTDATA,如果小于零,则会报IllegalArgumentException错误。

什么也不传入

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

如上述所说,当什么也不传入时,ArrayList会默认为DEFAULTCAPACITY_EMPTY_ELEMENTDATA

传入一个Collection接口的变量

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

由代码可以看出,首先我们把传入的变量赋值给elementData,当传入的变量长度(也就是现在elementData的长度)不为0的时候,判断传入的变量是否为Object[]类型的,如果不是则转化为Object类型。如果传入的变量长度为0,则为EMPTY_ELEMENTDATA。

3、常用方法

add 一个变量

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

我们可以看到,调用add方法首先会调用ensureCapacityInternal方法,我们先看一下这个方法

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

如果elementData的值为DEFAULTCAPACITY_EMPTY_ELEMENTDATA,那我们需要比较出DEFAULT_CAPACITY和minCapacity中的最大值,也就是DeFAULT_CAPACITY与当前的数组长度+1之间的最大值,然后调用ensureExplicitCapacity,那我们看一下ensureExplicitCapacity这个方法

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

我们发现这里多了一个以前没有提到过的变量modCount,而这个modCount是做什么用的呢?modCount代表的修改次数,主要是为了防止在多线程中该对象被其他线程修改,比如,一个线程在读取该对象,而另一个线程对该对象进行了增删操作,那样就会抛出异常。

然后如果传入的值减去现在该对象的长度大于零,那么就会调用grow这个方法,那么就有另外一个问题:为什么要比较DEFAULT_CAPACITY和minCapacity的大小呢?

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值