• Java中ArrayList各函数


    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进行排序,如在排序中出现数据修改错误,则会抛出多线程修改异常。
    
  • 相关阅读:
    快速排序?
    算法和数据结构?
    渲染一个react?
    移动端兼容适配?
    PWA全称Progressive Web App,即渐进式WEB应用?
    InnoDB一棵B+树可以存放多少行数据?
    移动端首屏优化?
    InnoDB什么时候会锁表?
    数组去重,多种方法?
    如何处理异形屏iphone X?
  • 原文地址:https://www.cnblogs.com/zhangxiaomao/p/14330589.html
Copyright © 2020-2023  润新知