Java容器ArrayList原理解析
这篇文章主要介绍了Java容器ArrayList原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
List是collection接口的实现类
List:
特点:有序,可重复
它有两个常用的实现类:
一。ArrayList:
特点:以数组的形式进行存储,因此随机访问速度较快,所有它适用于查询。
缺点:不适用于插入和删除的操作因为每次操作都需要移动数组中的元素。
根据源码我们能得出以下几点:
1.ArrayList在初始化的时候如果我们没有指定长度的话,它会有一个默认长度10,
privatestaticfinalintDEFAULT_CAPACITY=10;
2.如果我们在增加新元素的时候超过了原来的容量,那么ArrayList是怎么做的呢?
(底层扩容机制:扩容为原来的1.5倍)
这就涉及到了ArrayList的扩容机制,既然ArrayList是以数组形式存储的,那么肯定就继承了数组的特点一旦声明不可更改,那么既然不可更改,那java是怎么解决这个问题的呢?
transientObject[]elementData;
开头声明的这个就是一个临时的可变的数组为以后数组扩容做准备
publicbooleanadd(Ee){ ensureCapacityInternal(size+1);//IncrementsmodCount!! elementData[size++]=e; returntrue; }
上边代码的ensureCapacityInternal(size+1)就是扩容的开始
我们点进去源码继续深入
privatevoidensureCapacityInternal(intminCapacity){ ensureExplicitCapacity(calculateCapacity(elementData,minCapacity)); } privatevoidensureExplicitCapacity(intminCapacity){ modCount++; //overflow-consciouscode if(minCapacity-elementData.length>0) grow(minCapacity); }
看到这我们发现了ensureCapacityInternal中调用了ensureExplicitCapacity我们继续深入
privatestaticfinalObject[]DEFAULTCAPACITY_EMPTY_ELEMENTDATA={};//默认的空集合 privatestaticfinalintDEFAULT_CAPACITY=10;//默认10 privatestaticintcalculateCapacity(Object[]elementData,intminCapacity){//如果当前的elemenrData(当前的数据)是一个空的集合,获取下一步的扩容的容量 if(elementData==DEFAULTCAPACITY_EMPTY_ELEMENTDATA){ returnMath.max(DEFAULT_CAPACITY,minCapacity); } returnminCapacity; }
然后我们回到上一层
privatevoidensureExplicitCapacity(intminCapacity){ modCount++;//每次修改集合次数(AbstractList.class中的值) //overflow-consciouscode检测溢出 //如果最小所需容量>数组长度,就要扩容 if(minCapacity-elementData.length>0)grow(minCapacity);}
privatevoidgrow(intminCapacity){ //overflow-consciouscode intoldCapacity=elementData.length; intnewCapacity=oldCapacity+(oldCapacity>>1);//初始容量的1.5倍(1.8,1.7)(1.6是1.5倍+1) if(newCapacity-minCapacity<0) newCapacity=minCapacity;//如果还是不够就把需要的值赋值 if(newCapacity-MAX_ARRAY_SIZE>0) newCapacity=hugeCapacity(minCapacity);//判断大容量,下面代码 //minCapacityisusuallyclosetosize,sothisisawin: elementData=Arrays.copyOf(elementData,newCapacity);//这就是为什么以数组形式存储还可以扩容的原因 } privatestaticinthugeCapacity(intminCapacity){ if(minCapacity<0)//overflow内存溢出 thrownewOutOfMemoryError(); return(minCapacity>MAX_ARRAY_SIZE)?//三元运算 Integer.MAX_VALUE: MAX_ARRAY_SIZE; }
看完以上代码我们可以得出来如果不给初始值,默认值为10,扩容时候不是在原数组上做更改,而是copy了一个数组按1.5倍增长
3.ArrayList是线程不安全的。如果要实现线程安全可以使用synchronized关键字或者使用Collections.synchronizedList()方法如下:
List
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。