对于程序员而言,工作前期有好多会用,懂得如何使用就OK了,但是到了后期还想更进一步就不是简简单单的只会coding这么简单了,回想自己工作了这么些年,对什么都是浑浑噩噩,对什么都是求个一知半解,感觉太对不起程序员这么一个称号了.
下面我会主键的将一些常用的底层类做个分析,希望大家多多指正
第一章 深入理解ArrayList
通常我们使用ArrayList的时候会使用这种形式:List arrayList = new ArrayList();
问题1:为什么我们不使用ArrayList arrayList = new ArrayList();来进行对象的创建呢?
List是一个抽象类,这样体现了java的多态性,像ArrayList以及LinkedList都是实现多态的,增加接口的灵活性.我们调用使用只会使用到我们要用到的ArrayList()中的方法,在这里会对List方法进行重写或者新增一些方法
那么在我们创建ArrayList的时候要知道,ArrayList其实是一个Object类型的数组,对于add,remove,set都是针对这个数组进行的.
ArrayList arrayList = new ArrayList();生成对象的时候,Object[]是一个长度为0的数组
我们现在就来看下它在进行插入,移除,排序的操作实现方法,其中方法中的size就像是指针一样,我们都是根据这个size来当做当前最新的长度来计算
插入:
add():在第一次add的时候,会对这个数组增加一个DEFAULT_CAPACITY=10的长度,以后再对他进行add的时候都会复制出一个+1的数组方便后续操作.arrayList也是有最大长度Integer.MAX_VALUE .其中带参数的add()方法和下面addAll中说明差不多,这里就不做说明.
addAll():将要add的ArryaList转换为数组,将数组容器扩大为两个合并数组长度总和,然后利用System.arraycopy 来进行合并,其中size可以理解为指针.
addAll(int index,Collection c):带参数的addAll方法,目的是将c放入到指定列表的指定索引出,具体实现方式是
1:检查索引位置是否大于当前列表的长度,大于报超出索引异常
2:复制一个长度为两个列表长度和的数组
3:将原数组的index位置向后偏移index后续的数组内容,偏移位置在index~index+c.length后
4:将要加入的c列表放入到扩展后的列表的index~index+c.length中
get(int index):传入索引值直接返回对应数组中索引的值
set(int index, E element):在对应数组index位置更改值
remove(int index):首先我们就要明确这个remove是将其中一个索引值给删除,那么size就会对应的减一,我们根据System.arraycopy将index+1后面的值偏移到index位置上去,这样就实现了remove.
remove(Object o):移除检索到的第一个值.
clear():将size=0就解决所有问题了
remove(int fromIndex, int toIndex):将toIndex后面的值偏移到fromIndex位置,size就会跟着改变为size - (toIndex-fromIndex)
像其他的方法例如removeAll是针对删除其他列表对应的所有值,retainAll是删除对应列表其他的值,这个和addAll原理一致
ArrayList自己的iterator方法是重写了自己的Iterator方法,这里就不做说明
总结一下,ArrayList其实根本上就是一个数组,在增加的时候就会重新建立一个size+1的副本,删除的时候同样会创建一个副本进行索引偏移,所以说在查看的时候我们直接根据索引就可以很快的查看,但是在删除新增的相对的麻烦点.
如果有哪里说明不当的,请大家留言批评,大家一起学习一起进步