ArrayList
主要成员:
transient Object[] elementData; //用于存放数据的数组
private int size; //表示ArrayList的节点个数
public ArrayList(int initialCapacity):构造方法
时间O(1)
空间O(n) :分配initialCapacity大小的数组
临时对象:无
如initialCapacity > 0 则new一个initialCapacity大小Object数组,赋值给elementData。
如initialCapacity == 0 则给elementData赋值一个空Object数组。
其他情况抛异常。
public ArrayList() :构造方法
时间O(1)
空间O(1) :
临时对象:无
给elementData赋值一个空Object数组。
public ArrayList(Collection<? extends E> c) :构造方法
时间O(n):函数本身并无循环等操作,但c的toArray方法中一些实现会遍历整个集合,此时为O(n)
空间O(n):函数本身并未申请内存,但在c的toArray方法中最坏情况下需要重新构造数组,需分配内存
临时对象:无
首先调用c的toArray(),根据c的不同类型使用各自实现的toArray将c转换为Object数组。
如果elementData的length != 0则判断elementData的所属类是否等于Object[]的所属类,如不等则调用Arrays的copyOf带参方法,并在参数中写入Object[]的所属类,将copyOf方法返回的Object[]类型对象赋值给elementData。
如果elementData的length == 0则给elementData赋值一个空Object数组。
public void trimToSize() :将ArrayList的capacity修正到size大小
时间O(n):在size<elementData.length时,会将大于size的部分切除,最坏情况下几乎需遍历整个数组。
空间O(1)
临时对象:无
首先将modCount(修正次数)+1。
如果size小于elementData当前的length,则判断size是否为0, 为0则给elementData赋值空数组,否则调用Arrays的copyOf调整elementData数组,将大于size的部分切除。
public void ensureCapacity(int minCapacity):扩充数组容量
时间O(1)
空间O(1)
临时对象:无
如果elementData != 默认容量空数组,则给minExpand赋值为0,否则赋值为
DEFAULT_CAPACITY(final常量,值为10)。
如果传入的参数minCapacity>minExpand则,调用ensureExplicitCapacity方法进行扩充。
private void ensureExplicitCapacity(int minCapacity):如果需要扩充则扩充容量
时间O(1)
空间O(1)
临时对象:无
首先将modCount(修改次数)+1。
如果minCapacirty > 当前数组elementData的length,调用grow方法进行扩充。
private void grow(int minCapacity):扩充容量使其至少大于minCapacity
时间O(n) :最坏情况下Arrays.copyOf中会进行数组重构,创建一个新数组,并复制原数组的元素,复制时需遍历。
空间O(n):最坏情况下Arrays.copyOf中会创建一个新数组
临时对象:无
给oldCapacity赋值为elementData的length,给newCapacity赋值为oldCapacity+oldCapacity/2 (约等于1.5倍),如果newCapacity <minCapacity(传入的参数,新的最小容量),则给newCapacity 赋值为minCapacity,如newCapacity>MAX_ARRAY_SIZE(常量,约为Int最大表示范围)则调用hugeCapacity来获得最大的数组数量,并赋值给newCapacity。
最后调用Arrays.copyOf 重构数组。
private static int hugeCapacity(int minCapacity) :
时间O(1) :
空间O(1):
临时对象:无
minCapacity<0时抛异常。
如果minCapacity > MAX_ARRAY_SIZE则返回为int的最大表示范围否则返回 MAX_ARRAY_SIZE。
private static int calculateCapacity(Object[] elementData, int minCapacity) :计算容量
时间O(1)
空间O(1)
临时对象:无
如果elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA (默认容量空数组)则返回minCapacity 和 DEFAULT_CAPACITY中较大的一个,如不等则返回minCapacity。
public int size():返回size
时间O(1)
空间O(1)
临时对象:无
return size
private void ensureCapacityInternal(int minCapacity):增加容量
时间O(n):调用了ensureExplicitCapacity,并在里面调用gorw来增加容量
空间O(n):调用了ensureExplicitCapacity,并在里面调用gorw来增加容量
临时对象:无
首先使用calculateCapacity来获取最小容量。
调用ensureExplicitCapacity填入最小容量来进行扩充。
public boolean isEmpty():返回是否为空
时间O(1)
空间O(1)
临时对象:无
rutuen size == 0
public int indexOf(Object o):判断o在数组中第一次出现的位置
时间O(n):通过循环遍历数组
空间O(1)
临时对象:无
如果o为null则for循环正序遍历数组,使用==判断是否有元素为null,有则返回下标。
如o不为null,则for循环正序遍历数组,使用equals来判断是否有元素==o,有则返回下标。
如果没有则返回-1
public int lastIndexOf(Object o) :判断o在数组中最后一次出现的位置
时间O(n):通过循环遍历数组
空间O(1)
临时对象:无
如果o为null则for循环倒序遍历数组,使用==判断是否有元素为null,有则返回下标。
如o不为null,则for循环倒序遍历数组,使用equals来判断是否有元素==o,有则返回下标。
public boolean contains(Object o) :判断数组中是否包含对象o
时间O(n):调用了indexOf,需要遍历数组来判断
空间O(1)
临时对象:无
调用indexOf(o)查看o在数组中的位置,如果位置>=0则表示o在数组中,此时返回true,否则返回false
public Object clone() :返回ArrayList的浅拷贝,可能抛出拷贝不支持异常
时间O(n):copyOf方法进行拷贝时需要进行数组的遍历。
空间O(n):copyOf方法需要建立一个新数组在进行遍历复制。
临时对象:ArrayList<?> v 先构造了一个新ArrayList,在进行拷贝操作
调用super的clone方法(super中是native实现), 并使用Arrays的copyOf方法遍历elementData数组进行对象赋值,并将modCount赋值为0,最后返回拷贝好的新ArrayList。如在过程中出现异常则抛出。
public Object[] toArray() :返回ArrayList的数组格式
时间O(n):copyOf方法进行拷贝时需要进行数组的遍历。
空间O(n):copyOf方法进行拷贝时需要进行数组的遍历。
临时对象:无
调用Arrays的copyOf方法并返回结果。
public <T> T[] toArray(T[] a) :返回ArrayList的数组格式
时间O(n):copyOf方法进行拷贝时需要进行数组的遍历。
空间O(n):copyOf方法需要建立一个新数组在进行遍历复制。
临时对象:无
如果a的length<size则调用Arrays的copyOf方法,并转换为泛型类型T[],在返回。
否则调用System的arraycopy方法进行复制,如a的length>size则将a[size]至为null(表示之后为无效数据),最后返回a
E elementData(int index) :返回下标为index的元素
时间O(1)
空间O(1)
临时对象:无
将elementData[index]类型转为E 并返回。
public E get(int index) :返回下标为index的元素
时间O(1)
空间O(1)
临时对象:无
调用rengeCheck方法检查下标的合法性,不合法则抛出异常,否则调用elementData(int index)方法返回下标为index的元素。
public E set(int index, E element) 给数组的index节点赋值
时间O(1)
空间O(1)
临时对象:oldValue(用于存放被替换的Object对象)
调用rengeCheck方法检查下标的合法性,不合法则抛出异常。
调用elementData(int index)给oldValue赋值,并用elment替换elementData[index],返回被替换的旧对象。
public boolean add(E e):在ArrayList末尾增加一个元素
时间O(n):如容量足够时为O(1) ,如不够则需进行扩充,此时为O(n),最坏情况为O(n)
空间O(n):如容量足够时为O(1) ,如不够则需进行扩充,此时为O(n),最坏情况为O(n)
临时对象:参数中的e
首先调用ensureCapacityInternal来进行判断性扩充之后将elementData的size节点填入元素e,最后将size+1,返回true。
private void rangeCheckForAdd(int index) :检查下标是否合法
时间O(1)
空间O(1)
临时对象:无
判断如果index > size 或 index < 0 则不合法,抛出异常。
public void add(int index, E element):在ArrayList的index处插入一个元素
时间O(n):使用System的arraycopy方法复制时会遍历数组
空间O(n):使用System的arraycopy方法复制时会建立一个数组来拷贝
临时对象:无
使用rangeCheckForAdd方法检查下标,使用ensureCapacityInternal确保容量足够,调用System的arraycopy方法,将index及之后的元素全部向后移动一格,后给index节点赋值,在把size+1。
public E remove(int index) : 通过下标来删除一个元素
时间O(n):使用System的arraycopy方法复制时会遍历数组
空间O(n):使用System的arraycopy方法复制时会建立一个数组来拷贝
临时对象:无
使用 rangeCheck来检查下标,并将modCount+1,通过elementData方法来获取index位置的旧元素存入oldValue,在计算需要移动的元素个数,如个数大于0 调用System的arraycopy方法,将index之后的元素全部向前移动一格,后给最后一个节点赋值null,在把size-1,返回oldValue。
public boolean remove(Object o):删除数组中等于o的元素
时间O(n)
空间O(n)
临时对象:参数中的o
如果o == null,则遍历数组,判断是否有元素==null,如有则调用fastRemove方法进行删除,并返回true。
如果o != null,则遍历数组,通过equals判断是否有元素与o相同,如有则调用fastRemove方法进行删除,并返回true,
如果没有元素相同则返回false。
private void fastRemove(int index) :跳过边界检查的remove
时间O(n):使用System的arraycopy方法复制时会遍历数组
空间O(n):使用System的arraycopy方法复制时会建立一个数组来拷贝
临时对象:无
首先将modCount+1,并计算需要移动的次数,如果移动的次数大于0则调用System的arraycopy方法,将index之后的元素全部向前移动一格,后给最后一个节点赋值null,在把size-1。
public void clear() :删除所有的元素
时间O(n):遍历整个数组需O(n)
空间O(1)
临时对象:无
首先将modCount+1,在通过for循环遍历整个elementData数组,将所有节点全置null,最后将size置为0。
public boolean addAll(Collection<? extends E> c):将c整个加入到ArrayList中
时间O(n):使用System的arraycopy方法复制时会遍历数组
空间O(n):使用System的arraycopy方法复制时会建立一个数组来拷贝
临时对象:a
首先将调用c的toArray方法生成一个数组并赋值给a,并获取a的length,调用ensureCapacityInternal,填入参数size+numNew来进行扩充,并调用System的arraycopy方法将整个a复制到ArrayList的末尾,将size+numnew,返回numNew!=0。
public boolean addAll(int index, Collection<? extends E> c) :将c整个插入ArrayList中
时间O(n):使用System的arraycopy方法复制时会遍历数组
空间O(n):使用System的arraycopy方法复制时会建立一个数组来拷贝
临时对象:a
首先使用rangeCheckForAdd来检查下标合法性,首先将调用c的toArray方法并赋值给a,并获取a的length,调用ensureCapacityInternal,填入参数size+numNew来进行扩充,并计算需要移动的元素数量,如果要移动的数量大于0则调用System的arraycopy方法将需要移动的元素向后移动a的length位,后通过调用System的arraycopy方法将整个a插入到ArrayList中 ,将size + a的length位,返回numNew!=0。
protected void removeRange(int fromIndex, int toIndex):删除数组中的一段序列的元素
时间O(n):使用System的arraycopy方法复制时会遍历数组
空间O(n):使用System的arraycopy方法复制时会建立一个数组来拷贝
临时对象:无
首先将modCount +1,计算需要移动的数量,并调用 System.arraycopy方法将被删除的元素后面的所有元素前移,在计算新size,将新size到旧size之间的数组元素赋null,使其能被gc回收。最后修改size为最新的值。
private void rangeCheck(int index):检查index是否越上界
时间O(1)
空间O(1)
临时对象:无
如index >= size ,则表示下标越界,抛出异常。
private void rangeCheckForAdd(int index):检查index是否越界
时间O(1)
空间O(1)
临时对象:无
如index >= size 或 index < 0,则表示下标越界,抛出异常。
private String outOfBoundsMsg(int index):输出index和size
时间O(1)
空间O(1)
临时对象:无
return "Index: "+index+", Size: "+size;
public boolean removeAll(Collection<?> c):删除ArrayList包含在c中的元素。
时间O(n*m) batchRemove中通过for循环来遍历ArrayList,使c对ArrayList中的每个元素进行contains操作,contains调用了indexOf函数来进行判断,indexOf复杂度为O(n) ,故总复杂度为O(n*m)
空间O(1)
临时对象:无
调用Objects的requireNonNull方法来确保c不为空,在通过调用batchRemove方法来进行批量删除,如删除成功返回true,否则返回false。
public boolean removeAll(Collection<?> c):删除ArrayList中不包含在c中的元素。
时间O(n*m) batchRemove中通过for循环来遍历c,对c中的每个元素进行contains操作, contains调用了indexOf函数来进行判断,indexOf复杂度为O(n) ,故总复杂度为O(n*m)
空间O(1)
临时对象:无
调用Objects的requireNonNull方法来确保c不为空,在通过调用batchRemove方法来进行批量删除,如删除成功返回true,否则返回false。
public boolean retainAll(Collection<?> c):删除ArrayList包含在c中的元素。
时间O(n*m):batchRemove中通过for循环来遍历ArrayList,使c对ArrayList中的每个元素进行contains操作,contains调用了indexOf函数来进行判断,indexOf复杂度为O(n) ,故总复杂度为O(n*m)
空间O(1)
临时对象:无
调用Objects的requireNonNull方法来确保c不为空,在通过调用batchRemove方法来进行批量删除,如删除成功返回true,否则返回false。
public ListIterator<E> listIterator(int index) :返回一个ListItr遍历器对象。ListItr相比Itr多了一些List的专用操作,如add、set等。并且 ListItr可以向前遍历
时间O(1)
空间O(1)
临时对象:无
如果下标越界则抛出异常,如果没有越界则返回一个ListItr遍历器对象,该对象的游标cursor为index。
public ListIterator<E> listIterator() :返回一个ListItr遍历器对象。
时间O(1)
空间O(1)
临时对象:无
返回一个ListItr遍历器对象,该对象的游标cursor为0。
public Iterator<E> iterator():返回一个Itr遍历器对象。
时间O(1)
空间O(1)
临时对象:无
返回一个Itr遍历器对象,该对象的游标cursor为0。
public List<E> subList(int fromIndex, int toIndex) :返回一个子List
时间O(1)
空间O(1)
临时对象:无
调用subListRangeCheck进行边界判断,如越界则抛异常,否则返回一个SubList对象在其构造函数中填入this(表示原ArrayList),fromIndex,toIndex等, SubList隐藏了父ArrayList中的元素,但并为进行删除。在之后修改subList后,父List数组也会产生变化
public void forEach(Consumer<? super E> action):遍历列表执行某些方法
时间O(n):action中是循环调用的
空间O(1)
临时对象:无
首先调用Objects的requireNonNull方法,检查action不为空,在使用for循环调用action的accept来对每一个元素执行方法,如在操作中modCount值被修改则抛出多线程修改异常。
public Spliterator<E> spliterator():返回一个并行迭代器
时间O(1)
空间O(1)
临时对象:无
直接return一个ArrayListSpliterator对象
public boolean removeIf(Predicate<? super E> filter) :
时间O(n):for循环进行了遍历
空间O(1)
临时对象:无
首先调用Objects的requireNonNull方法对filter进行有效性判定。其次调用for循环对数组中的元素进行条件验证,并将符合删除条件的元素记录,将下标放入bitset中。之后在通过for循环进行遍历删除。
public void replaceAll(UnaryOperator<E> operator):对数组元素进行统一的修改
时间O(n):
空间O(1):
临时对象:无
首先判断operator的合法性,在通过for循环进行数组遍历,对每个元素执行operator的apply操作,如在过程中modCount被修改则抛出多线程修改异常,如没有修改,则将modCount+1。
public void sort(Comparator<? super E> c) :根据c的排序规则对ArrayList进行排序
时间O(nlogn):使用了timSort算法进行排序
空间O(n):使用了timSort算法进行排序
临时对象:无
调用Arrays的sort方法,对ArrayList进行排序,在Arrays的sort方法中使用timSort进行排序,如在排序中出现数据修改错误,则会抛出多线程修改异常。