Java ArrayList
                           
天天向上
发布: 2025-03-02 18:39:37

原创
447 人浏览过

ArrayList 是 Java 集合框架中非常常用的一种实现类,属于 List 接口的实现,它基于动态数组来实现集合,因此具有按索引快速访问元素的特点。ArrayList 允许存储 重复元素,并且是 有序的,即元素的插入顺序会被保持。

1. ArrayList 的基本特性

  • 大小可变ArrayList 会自动调整数组的大小以适应元素的增减。初始容量是 10,当 ArrayList 中的元素超过当前容量时,它会扩容(通常是扩展为原来大小的 1.5 倍)。
  • 支持随机访问:通过索引访问元素的时间复杂度是 O(1)。
  • 不支持线程安全ArrayList 不是线程安全的,如果多个线程并发修改同一个 ArrayList,需要额外的同步处理。
  • 允许存储 nullArrayList 可以存储 null 元素。

2. ArrayList 的常用构造函数

// 默认构造函数,初始容量为 10
ArrayList<E> list = new ArrayList<>();

// 指定初始容量
ArrayList<E> list = new ArrayList<>(int initialCapacity);

// 基于另一个集合创建 ArrayList
ArrayList<E> list = new ArrayList<>(Collection<? extends E> c);

3. ArrayList 常用方法

3.1 添加元素

  • add(E e):将元素添加到列表的末尾。
  • add(int index, E element):在指定的索引位置插入元素。
ArrayList<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add(1, "Orange"); // 在索引 1 插入 "Orange"

3.2 删除元素

  • remove(Object o):删除第一次出现的指定元素。
  • remove(int index):删除指定位置的元素。
  • clear():删除所有元素。
list.remove("Banana"); // 删除 "Banana"
list.remove(0);        // 删除索引为 0 的元素
list.clear();          // 清空 ArrayList

3.3 访问元素

  • get(int index):获取指定索引位置的元素。
  • set(int index, E element):替换指定索引位置的元素。
String fruit = list.get(1); // 获取索引为 1 的元素
list.set(1, "Grapes");     // 替换索引为 1 的元素

3.4 查询元素

  • contains(Object o):检查列表是否包含某个元素。
  • indexOf(Object o):返回指定元素首次出现的索引,如果没有找到返回 -1。
  • size():返回 ArrayList 中的元素个数。
  • isEmpty():判断 ArrayList 是否为空。
boolean containsApple = list.contains("Apple"); // 检查是否包含 "Apple"
int index = list.indexOf("Grapes"); // 获取 "Grapes" 的索引
int size = list.size(); // 获取 ArrayList 的大小
boolean isEmpty = list.isEmpty(); // 判断是否为空

3.5 遍历元素

  • 使用 for-each 循环:
for (String fruit : list) {
    System.out.println(fruit);
}
  • 使用 Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}
  • 使用 for 循环:
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

3.6 转换为数组

  • toArray():将 ArrayList 转换为数组。
Object[] array = list.toArray();
  • toArray(T[] a):将 ArrayList 转换为指定类型的数组。
String[] array = list.toArray(new String[0]);

3.7 其他常用方法

  • removeAll(Collection<?> c):删除列表中所有与给定集合 c 相同的元素。
  • retainAll(Collection<?> c):保留列表中所有与给定集合 c 相同的元素。
  • subList(int fromIndex, int toIndex):返回指定范围的子列表(不包括 toIndex)。
  • ensureCapacity(int minCapacity):确保列表有足够的容量来容纳至少 minCapacity 个元素。

4. ArrayList 的性能

  • 访问元素:由于 ArrayList 是基于动态数组实现的,获取元素是 O(1) 的时间复杂度。
  • 添加元素:如果是在末尾添加元素,时间复杂度为 O(1),但是当需要扩容时(元素数量超过当前容量),时间复杂度是 O(n)。
  • 插入和删除元素:在中间或头部插入或删除元素时,需要移动其他元素,因此时间复杂度为 O(n)。

5. 使用 ArrayList 的场景

  • 随机访问ArrayList 在需要频繁通过索引访问元素的场景中表现优异。
  • 元素个数变化较少:当元素个数变化较少时,使用 ArrayList 很方便,因为它的查询效率高。
  • 排序操作:由于 ArrayList 允许访问所有元素,因此可以通过集合类中的 sort() 方法快速排序。

6. 线程安全问题

ArrayList 默认不是线程安全的。如果在多线程环境中同时访问和修改 ArrayList,则可能会导致数据不一致问题。在这种情况下,可以使用:

  • Collections.synchronizedList():将 ArrayList 包装成线程安全的列表。
  • CopyOnWriteArrayList:适用于写操作较少的多线程环境,它会在每次修改时复制整个数组。
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());

7. ArrayList 与 LinkedList 的比较

特性ArrayListLinkedList
底层实现动态数组双向链表
随机访问快速 O(1)慢 O(n)
插入/删除操作慢 O(n),尤其是中间位置快 O(1),在头尾插入和删除较快
内存占用内存占用较小每个节点额外存储前后节点引用
适用场景频繁查询,少量插入删除操作频繁插入删除,尤其是头尾位置操作

小结

ArrayList 是一个灵活且高效的集合类,适用于需要快速随机访问和较少修改的场景。它是 Java 集合框架中最常用的类之一,对于需要频繁读取但较少插入或删除元素的应用场景非常合适。如果需要更频繁的插入和删除操作,可能需要考虑 LinkedList。更多详细内容请关注其他相关文章。

发表回复 0

Your email address will not be published. Required fields are marked *