最近在阅读ArrayList的源码,把自己的想法记录下来,就当是一个笔记。
我们先总览一下ArrayList的继承关系。
ArrayList继承了AbstractList,实现了RandomAccess,Serializable和Cloneable接口。
RandomAccess接口:
这个接口是一个标志接口,表明实现这个接口的List是支持随机访问的,并且普通for循环的方式要比迭代器的循环方式效率更高一些。
Serializable接口:
用于实现序列化。
Cloneable接口:
Cloneable也是一个标志接口,只有实现了这个接口,并且重写了Object类中的Clone方法,才可以成功调用clone方法,否则会抛出CloneNotSupportedException异常,如下所示。
AbstractList类:
AbstractList是一个抽象类,实现了List接口,但是其中只有一个抽象方法:
ArrayList中的一些方法。
- 构造方法。
首先是带一个int参数的构造方法,允许用户输入>= 0的整形参数,如果小于0,则会抛出IllegalArgumentException。
然后是一个不带参数的构造方法,默认为一个Object数组。
还有一个就是参数为Collection的构造方法,代码如下。
简单来说,就是传入一个Collection集合,然后返回一个与传入集合相同的新的ArrayList。
- add方法。
这是add方法,如果ArrayList的size已经到了数组的最大值,那么就会执行一个叫做grow()的扩容方法,会在原大小的基础上扩容1.5倍。如果新得数组大小newCapacity小于MAX_ARRAY_SIZE则返回newCapacity,如果大于的话会执行hugeCapacity方法,有可能返回Integer.MAX_VALUE.
- add(index,element).
这个方法用于在指定的位置插入指定的元素,在这个元素之后的所有数据会向右移动。
通过rangeCheckForAdd方法去比较index和集合大小,如果index>集合的size或者<0,就会抛出IndexOutOfBoundsException。
- remove方法。
ArrayList中的remove方法有好几个,可以根据元素在ArrayList中的index进行删除,也可以根据元素内容进行删除,甚至还可以直接removeAll来把参数中包括的集合内容给清空。
首先remove(index)方法,删除list下标为index的元素,后续所有元素向左移动。
然后是remove(object)方法,这个方法会删除第一个符合条件的object。
最后就是removeAll了,这个方法会把参数集合中所有的元素给删除掉,不会像remove(object)方法那样把第一次出现的元素给删除掉。
- contains方法。
contains方法用来判断集合中是否包含指定的元素,源码中是通过一次循环来实现的,分别判断指定元素是否为null来进行判断,返回对应的下标,如果下标>=0的话说明集合中包含指定元素。
- get方法。
判断index是否超过集合的最大值,是否小于0,如果都不符合的话,返回集合中的第index个元素。
- isEmpty()方法。
这个就比较简单了,如果size==0,说明集合为空,返回true,反之则是false。
- size()方法。
用于返回集合的大小。
- set方法。
先是判断传入的index是否合法,如果index<0或者index>=集合的长度会抛出IndexOutOfBoundsException异常。如果校验没有问题的话,会把下标为index的数据替换为传入的值。
写的不是很好,如果有什么不对的地方欢迎指点。