ArrayList继承自AbstractList,AbstractList为“random access”的数组提供了基本的实现。随机访问数据是相对于顺序访问数据而言,例如链表的形式。AbstractSequentialList为链表形式的顺序访问提供了基本实现。AbstractList提供了默认的随机访问数据的iterator。AbstractList继承自AbstractCollection,AbstractCollection为Collection提供了基本实现。
contains
AbstractCollection实现了查询是否包含某一个元素的方法。最好使用Iterator遍历集合中的元素,因为可以屏蔽集合内部元素存储的具体实现,并且根据不同的数据存储特点,优化访问策略。这里还可以正确查找null元素,需要注意的是对null元素的查询需要特别的处理,有时候自己实现方法时,往往会忽略传入参数为null时的处理,导致方法无法处理特殊情况。
|
|
toArray
toArray
方法将容器中的元素转化为数组的形式。这里元素的复制,采用的是直接复制引用。这里还考虑到了并发运算时,元素数量在复制时产生变化的情况,当数量减少时,就用Arrays.copy()
截取结果。当数量增加时,会调用finishToArray
函数扩容。
|
|
在finishToArray函数中,对容量每次扩展1/2+1的大小,并且会检查是否会超过设定的最大数组长度MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
。如果长度超过了限定值,则以原容量+1为底线,返回一个最大容量。最后返回的数组也会修剪掉多余的位置。
|
|
这里有一个toArray
的重载,需要传入一个数组作为参数,据我观察,目的是将集合中的元素存入指定的数组,重利用已有数组的存储。如果元素过多,而目标数组容纳不下,只能重新申请数组来进行存储。
|
|
removeAll
removeAll
方法删除目标集合中的所有重叠元素。Iterator可以做到在遍历时,安全的删除元素,而通过index循环删除则可能导致index偏移。
|
|
toString
AbstractCollection的toString实现,比较令我震惊的是e == this
的作用。这里为什么要判断打印的内容是否为自己本身?因为sb.append(e == this ? "(this Collection)" : e);
会调用e
的toString函数来生成字符串,若不加判断,则会形成无限的toString递归调用。我猜想一下,估计当时toString的实现者没有注意到该问题的存在,直到该bug出现。
|
|