Collection源码分析(一):ArrayList源码分析

ArrayList 继承至父类 AbstractList实现接口 List,RandomAccess,Cloneable克隆接口,Serializable可序列化接口

注意到以下三个主要变量 两个静态变量(存在于JVM的Method Area 方法区)一个Object得数组类型

其中EMPTY_ELEMENTDATA 是new ArrayList()时初始化得一个空对象数组

初始化长度为DEFAULT_CAPACITY得值

来看arrayList的几个主要方法

添加方法主要调用ensureCapacityInternal方法 这个方法 如下 主要是做长度判断的 如果加入的对象使得arrayList得长度 超过默认得10之后 会做grow操作 就是增长操作

增长操作则是在原有得长度 len*2+len  将原有得数组复制到新的数组里面 并赋值回去 旧的数组 在经过一次GC之后消亡。下面来看get操作

检查index值是否在长度之内 如果不是抛出indexoutofBoundsException 数组越界异常

如果在 这直接通过数组下标获取对象值 返回。

-----------------------------------------------------------------------这里是分割线

鉴于工作中碰到remove的操作 恰好看了看这块 还是准备把心得写下来 已做不时之需

一下主要探讨 remove(Object) 和removeAll(Collections)

1.可以看到remove 中主要做的操作是更具下标遍历数组 然后调用Object.equals方法 这个方法源码如下

比较的是两个对象的地址。这个涉及到 java虚拟机中对象的存储结构 当两个对象数据完全一样的时候 java虚拟机不会重新创建一个对象 而是将两个变量指向同一块内存区

如 String a="123" ,String b=new String("123"),a和b引用的是同一块地址

2.找到相同的对象之后,拿到他的下标index 调用fastRemove方法 遍历index+1之后的元素 将其全部前挪一位 并将最后一个元素置为Null 

在经过一次Minor GC之后 这个地方的内存将会被释放

removeAll(Collection)

源码中使用三行代码就完成 将所有不存在与参数列表C的元素从数组 elementDate 0开始重新赋值 组装成新的数组 这里complement为false

然后以w为开始 遍历 并将元素赋值为null 注意 第一个IF 是用来处理contains异常使用的 当抛出异常的时候 r是不等与size的 会走第一个if 如果不抛出异常 会直接走第二个IF

总结:以上可以看书 ArrayList集合 是基于数组实现的一个数据结构 数组元素为Object

增长机制为 新建一个为原来3倍长的数组 将元素复制过去即可 

附上JVM虚拟机内存结构模型文档

https://blog.csdn.net/luomingkui1109/article/details/72820232

猜你喜欢

转载自my.oschina.net/u/2970507/blog/1796320