ArrayList源码探险记

Arraylist:
基本知识点:
1.arrayList 内部构造是一个数组,所以构造时存在着一定的容量(负载因子),所以当数组列表满了的时候会出现自动扩容的状态。

2.第二个知识点很简单,该类不是一个线程安全类,所以当你在使用迭代器进行的迭代的时候你不能修改其中的数据,不然会有一个ConcurrentModificationException。这样的运行失败问题也称为快速失败。

源码分析:

1、跟踪ArryayList() 构造函数之后有惊喜:

如果调用该构造函数,arrayList内部构造会默认将指针指向一个空的数组(EMPTY_ELEMENTDATA),并且在第一调用add()方法之后才会根据默认容量大小(DEFAULT_CAPACITY)大小进行扩容,以后的每次扩容都是n+n的平方

(int newCapacity = oldCapacity + (oldCapacity >> 1))

而扩容的时候就需要把旧的数组里面的东西copy到新的数组里面去,会导致内容消耗。所以,如果你使用ArrayList的空构造函数的时候,那么就默认了你务必会进行一次扩容。然后我就自己在想,为什么要设计这样,为什么不一new一个ArrayList就直接构造一个大小(elementData)为10的数组呢?
我自己的猜想是这样的,java工程师应该是想模拟数组的结构,因为有时候或许new 一个ArrayList 就是需要让它为空的,或者对于从一个空数组复制数据到一个新的数组

Arrays.copyOf(elementData, newCapacity)

消耗的性能不值一提吧。所以查杀完源码之后,以后对于自己编写的程序一定要注意,如果明确知道或者大概知道数据量的大小的话,要提前输入ArrayList的容量,减少少ArrayList扩容对性能的影响。

2.里面存在size记录当前真实的存储容量。

发现trimToSize()方法,可以把当前未存储的数组空间的切除,即通过数组复制的方式来调整ArrayList缓存数组的大小

public void trimToSize() {
        modCount++;
        if (size < elementData.length) {
            elementData = Arrays.copyOf(elementData, size);
        }
    }

3.查询元素是否存在与查询元素的坐标需要遍历数组,时间复杂度为O(n)

4.toArray方法是负责一个新的数组返回出去,防止栈上逃逸

5.remove方法只是单纯的让具体坐标上面的元素为空,并不会使后置元素往前移动

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值