了解ArrayList

33 阅读4分钟

ArrayList

ArrayList是List接口下的一个实现类

public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable

ArrayList有两种构造方法

  • 无参构造: 1.8 之后是创建一个长度为0的容器,在第一次添加后扩容默认库容长度10
  • 第二个是传入一个储存空间的大小

ArrayList的常用实现方法

ArrayList底层是用数组实现的存储。

查询效率高,增删效率低,线程不安全,使用频率很高。

public static void main(String[] args) {
    List<String> all = new ArrayList<String>(); // 实例化List对象, 并指定泛型类型
    all.add("hello "); // 增加内容, 此方法从Collection接口继承而来
    all.add(0, "LAMP ");// 增加内容, 此方法是List接口单独定义的
    all.add("world"); // 增加内容, 此方法从Collection接口继承而来
    all.remove(1); // 根据索引删除内容, 此方法是List接口单独定义的
    all.remove("world");// 删除指定的对象
    System.out.print("集合中的内容是: ");
    for (int x = 0; x < all.size(); x++) { // size()方法从Collection接口继承而来
        System.out.print(all.get(x) + "、 "); // 此方法是List接口单独定义的
    }
}
​
/**
 *  ArrayList 常用方法
 *  void clear() 从此列表中删除所有元素。
 *  boolean addAll(Collection<? extends E> c) 将指定集合中的所有元素按指定集合的Iterator返回的顺序附加到此列表的末尾。
 *  void forEach(Consumer<? super E> action) 对 Iterable每个元素执行给定操作,直到处理 Iterable所有元素或操作引发异常。
 *  E get(int index) 返回此列表中指定位置的元素。
 *  int indexOf(Object o) 返回此列表中第一次出现的指定元素的索引,如果此列表不包含该元素,则返回-1。
 * boolean isEmpty() 如果此列表不包含任何元素,则返回 true 。
 * Iterator<E> iterator() 以适当的顺序返回此列表中元素的迭代器。
 * int lastIndexOf(Object o) 返回此列表中指定元素最后一次出现的索引,如果此列表不包含该元素,则返回-1。
 * ListIterator<E> listIterator() 返回此列表中元素的列表迭代器(按适当顺序)。
 * ListIterator<E> listIterator(int index) 从列表中的指定位置开始,返回列表中元素的列表迭代器(按正确顺序)。
 * E remove(int index) 删除此列表中指定位置的元素。
 * boolean remove(Object o) 从该列表中删除指定元素的第一个匹配项(如果存在)。
 * boolean removeAll(Collection<?> c) 从此列表中删除指定集合中包含的所有元素。
 * boolean removeIf(Predicate<? super E> filter) 删除此集合中满足给定谓词的所有元素。
 * protected void removeRange(int fromIndex, int toIndex) 从此列表中删除索引介于 fromIndex (含)和 toIndex (独占)之间的所有元素。
 * boolean retainAll(Collection<?> c) 仅保留此列表中包含在指定集合中的元素。
 * E set(int index, E element) 用指定的元素替换此列表中指定位置的元素。
 * int size() 返回此列表中的元素数。
 * Spliterator<E> spliterator() 在此列表中的元素上创建late-binding和故障快速 Spliterator 。
 * List<E> subList(int fromIndex, int toIndex) 返回指定的 fromIndex (包含)和 toIndex (不包括)之间的此列表部分的视图。
 * Object[] toArray() 以适当的顺序(从第一个元素到最后一个元素)返回包含此列表中所有元素的数组。
 * <T> T[] toArray(T[] a) 以适当的顺序返回包含此列表中所有元素的数组(从第一个元素到最后一个元素); 返回数组的运行时类型是指定数组的运行时类型。
 * void trimToSize() 将此 ArrayList实例的容量调整为列表的当前大小。
 *
*/

ArrayList源码解析

ArrayList可以通过构造方法在初始化的时候指定底层数组的大小。

通过无参的构造方法ArrayList()初始化,则赋值底层数组Object[] elementData为一个默认空数组Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}所以数组容量为0,只有真正对数据进行add时,才分配默认的DEFAULT_CAPACITY = 10的初始容量。

有无参构造器和有参构造器,无参就是默认大小,有参会进行判断.

比如有一个长度为10的数组,现在我们要新增一个元素,发现已经满了,那ArrayList会重新定义一个长度为10+10/2的数组,也就是长度为15的数组。然后把原数组的数据,原封不动的复制到新的数组中,这个时候在把指向原数组的地址换到新数组,ArrayList这样就完成了扩容的操作。

它有指定index新增,也有直接新增,在这之前它会有一步校验长度的判断ensureCapacityInternal,就是如果长度不够,需要进行扩容。

在扩容的时候,采用了位运算,右移一位,也就是除2,用位运算效率更高。

增删时的快慢取决于你删除的元素离数组末端有多远,ArrayList拿来作为堆栈还是挺合适的,push和pop操作完全不涉及数据移动操作。

参考

blog.csdn.net/SeekN/artic…

juejin.cn/post/701400…