现在的位置: 首页 > 综合 > 正文

java集合实现–02 –源代码学习–集合增加对象原理

2018年05月09日 ⁄ 综合 ⁄ 共 4040字 ⁄ 字号 评论关闭

其实上次我们已经看了ArrayList对象创建后产生的一些现象,下面我们通过源码在来看看往ArrayList集合里面操作对象都有什么现象:

 

1、增加一个对象,首先看下源代码:

 

 

 

 

 

2、我们可以看出它其实是有两个增加对象的方法,一个就是直接增加,另外一个就是指定位置直接增加,其实他们两个是有很大的不同

 

。好,那么我们先看看他直接增加的时候是什么样的一个过程:

 

                a) 我们看见增加的第一部里面有个 //Increments modCount!! 的注释--即扩大容器,那么我们进去看看注释前面里面

 

的方法:

 

 

 

从这个地方的源代码我们可以看出:其实它是判断增加对象后的 minCapacity 是否比之前容器的size(oldCapacity)大,如果大

 

的话就开始扩充容器,扩充容器的算法是     (size * 3 )/2 + 1 , 它跟vector是不一样的扩容算法,vector是 size * 2,

 

接着我们可以看到。然后它又检查了一次,然后通过数组的静态工具类Arrays的copyOf方法来扩充了容器,最后返回增加方法:

 

 

 

增加了一个对象,由上面我们还可以看出,其实如果ArrayList是按照正常的增加,即在后面增加对象,其实并没有涉及内容移动

 

只有在容器不够的时候扩充容器,并无很大的内容开销,换句话说其实它增加一个对象是开销是基本常量的时间。

 

                  b)现在我们来看看在ArrayList指定的位置增加一个对象,好,咱们看看它实现的源代码:

 

 

 

 

   从源代码上我们可以看出,它其实是先判断要增加的位置是否在容器的容量范围内,如果不在,则抛出了我们很熟悉的

 

异常  IndexOutBoundsException();  恩~不错,下次如果你不小心捉到这样的异常可千万别说这是什么原因了咕~~(╯﹏╰)b

 

。好了,我们接着往下看,又看见我们刚刚说的扩容,这里就不在进去看了。接下来就是要在指定位置增加某个对象。

 

首先,它会用System.arraycopy() 方法把原来的对象从要指定增加的位置向后拷贝一个位置,比如:

 

现在又个集合有: 1,2,3,4,5 的5个对象,我们要在2位置上增加一个:a 其实它的实现方法是 把  3,4,5 往后面拷贝,这个时候数组

 

变成: 1,2,3,3,4,5 。然后我们在往下看它在往指定的位置把刚刚指定的对象放上去,这个时候就是:1,2,a,3,4,5可以看见它就是

 

我们想要的结果了。要了解到这个主要是要理解System.arraycopy();方法的使用则可以了解。我们也可以看见其实往ArrayList

 

里面指定的位置增加一个对象,如果我们增加的位置不是最后的位置,其实它也没有涉及内存的移动,花费时间跟正常增加一个对象

 

也是一样的。

 

其实在指定的位置增加对象还有个问题:比如你指定的位置刚刚好是现在的容易的size + 1的位置,我们是可以正常增加的

 

 

 

从这句代码我们可以看的出,然而如果你增加的位置超过size + 1是会有异常的,这个大家千万要注意了额。额外的说个问题,

 

很多人觉得很奇怪,为什么我们System.out.println()对象的时候只是打出个地址,而我们打印集合的时候则会看见里面的对

 

象,这个我们就要追溯到它们的抽象类了,我们会在AbstractCollection里面看见它重写了toString() 方法:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

抱歉!评论已关闭.