杰瑞科技汇

ArrayList常用方法有哪些?

目录

  1. 核心概念与特点
  2. 构造方法
  3. 核心操作方法
    • 添加元素
    • 删除元素
    • 获取元素
    • 修改元素
    • 查询判断
  4. 遍历方法
  5. 工具方法
  6. 性能分析
  7. 代码示例

核心概念与特点

在深入方法之前,理解 ArrayList 的本质很重要:

ArrayList常用方法有哪些?-图1
(图片来源网络,侵删)
  • 动态数组:它的底层是一个数组,当元素数量超过数组容量时,它会创建一个更大的新数组,并将旧数组的元素复制到新数组中(这个过程称为扩容)。
  • 优点
    • 随机访问快:通过索引访问元素的时间复杂度是 O(1)。
    • 尾部添加/删除快:在列表末尾添加或删除元素,时间复杂度是 O(1)(不考虑扩容)。
  • 缺点
    • 中间插入/删除慢:在列表中间插入或删除元素,需要移动大量元素,时间复杂度是 O(n)。
    • 扩容有开销:当容量不足时,扩容操作会消耗时间和内存。

构造方法

在创建 ArrayList 实例时,有几种构造方式:

import java.util.ArrayList;
import java.util.List;
public class ArrayListConstructor {
    public static void main(String[] args) {
        // 1. 默认构造函数:创建一个初始容量为 10 的空列表
        List<String> list1 = new ArrayList<>();
        System.out.println("默认容量: " + ((ArrayList<?>) list1).size()); // 输出 0
        // 注意:ArrayList没有直接获取容量的public方法,但源码中是10
        // 2. 指定初始容量的构造函数:适用于已知大概元素数量,避免频繁扩容
        List<Integer> list2 = new ArrayList<>(20);
        System.out.println("指定容量列表初始大小: " + list2.size()); // 输出 0
        // 3. 使用另一个集合初始化:新列表包含指定集合的所有元素
        List<String> existingList = new ArrayList<>(Arrays.asList("A", "B", "C"));
        List<String> list3 = new ArrayList<>(existingList);
        System.out.println("使用集合初始化: " + list3); // 输出 [A, B, C]
    }
}

核心操作方法

这是 ArrayList 最常用的一组方法。

添加元素

方法 描述 时间复杂度 示例
add(E e) 将元素 e 追加到列表的末尾。 O(1) (均摊) list.add("Apple");
add(int index, E e) 将元素 e 插入到列表的指定 index 位置。 O(n) list.add(1, "Banana");
addAll(Collection<? extends E> c) 将集合 c 中的所有元素追加到列表末尾。 O(m) (m为集合c的大小) list.addAll(Arrays.asList("Cherry", "Date"));
addAll(int index, Collection<? extends E> c) 将集合 c 中的所有元素插入到列表的指定 index 位置。 O(n + m) list.addAll(2, anotherList);

删除元素

方法 描述 时间复杂度 示例
remove(Object o) 删除列表中第一个出现的元素 o,如果元素不存在,则不改变列表。 O(n) list.remove("Apple");
remove(int index) 删除列表中指定 index 位置的元素,并返回被删除的元素。 O(n) String removed = list.remove(0);
clear() 清空列表,移除所有元素。 O(n) (在某些JVM实现中) list.clear();

获取元素

方法 描述 时间复杂度 示例
get(int index) 返回列表中指定 index 位置的元素。 O(1) String fruit = list.get(0);
size() 返回列表中的元素数量。 O(1) int count = list.size();

修改元素

方法 描述 时间复杂度 示例
set(int index, E e) 用元素 e 替换列表中指定 index 位置的元素,并返回被替换掉的旧元素 O(1) String oldFruit = list.set(0, "Apricot");

查询判断

方法 描述 时间复杂度 示例
contains(Object o) 如果列表中包含元素 o,则返回 true O(n) boolean hasBanana = list.contains("Banana");
isEmpty() 如果列表不包含任何元素,则返回 true O(1) boolean empty = list.isEmpty();
indexOf(Object o) 返回元素 o 在列表中第一次出现的索引,如果列表不包含该元素,则返回 -1。 O(n) int index = list.indexOf("Banana");
lastIndexOf(Object o) 返回元素 o 在列表中最后一次出现的索引,如果列表不包含该元素,则返回 -1。 O(n) int lastIndex = list.lastIndexOf("Banana");

遍历方法

遍历 ArrayList 有多种方式,各有优劣。

for-each 循环 (推荐)

最简洁、最常用的方式,适用于只读遍历。

ArrayList常用方法有哪些?-图2
(图片来源网络,侵删)
for (String fruit : list) {
    System.out.println(fruit);
}

传统 for 循环

当需要知道元素的索引时使用。

for (int i = 0; i < list.size(); i++) {
    String fruit = list.get(i);
    System.out.println("Index " + i + ": " + fruit);
}

使用迭代器 (Iterator)

这是最安全、最标准的遍历方式,尤其是在遍历过程中需要删除元素时。

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    String fruit = iterator.next();
    if ("Banana".equals(fruit)) {
        iterator.remove(); // 安全地删除当前元素
    }
}

注意:在迭代过程中,不能使用 list.remove() 方法,否则会抛出 ConcurrentModificationException,必须使用迭代器自己的 remove() 方法。

使用 Java 8 Stream API (函数式风格)

适合进行复杂的链式操作、过滤、转换等。

ArrayList常用方法有哪些?-图3
(图片来源网络,侵删)
list.stream()
    .filter(fruit -> !fruit.startsWith("A")) // 过滤掉以A开头的元素
    .forEach(System.out::println);         // 打印剩余元素

工具方法

方法 描述
toArray() 将列表转换为一个Object 类型的数组
toArray(T[] a) 将列表转换为一个指定类型的数组,这是更常用的重载方法。
clone() 创建 ArrayList 的浅拷贝。

toArray 示例:

List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
// 1. 转换为 Object 数组
Object[] objArray = list.toArray();
System.out.println(Arrays.toString(objArray)); // [A, B, C]
// 2. 转换为指定类型的数组 (推荐方式)
String[] strArray = list.toArray(new String[0]);
System.out.println(Arrays.toString(strArray)); // [A, B, C]
// 如果指定数组长度不够,会创建一个新数组
String[] strArray2 = list.toArray(new String[5]);
System.out.println(Arrays.toString(strArray2)); // [A, B, C, null, null]

性能分析总结

操作 时间复杂度 原因
add(E e) (尾部添加) O(1) (均摊) 大部分情况下是直接在数组末尾添加,只有在扩容时,需要复制所有元素,所以是均摊的 O(1)。
add(int index, E e) (中间插入) O(n) 需要将 index 位置之后的所有元素都向后移动一位。
remove(int index) (中间删除) O(n) 需要将 index 位置之后的所有元素都向前移动一位。
get(int index) O(1) 直接通过索引计算数组位置,访问速度极快。
set(int index, E e) O(1) get,直接通过索引定位并修改。
contains(Object o) O(n) 需要遍历整个数组,逐个比较。
remove(Object o) O(n) 需要先遍历找到元素,再进行移动。
  • ArrayList 非常适合:需要频繁随机访问元素,或者主要在列表末尾进行增删操作的场景。
  • ArrayList 不适合:需要在列表中间频繁插入或删除元素的场景,LinkedList 会是更好的选择。

完整代码示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ArrayListMethodsDemo {
    public static void main(String[] args) {
        // 1. 创建和初始化
        List<String> fruits = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));
        System.out.println("初始列表: " + fruits);
        // 2. 添加元素
        fruits.add("Date"); // 尾部添加
        System.out.println("添加 Date 后: " + fruits);
        fruits.add(1, "Blueberry"); // 中间插入
        System.out.println("在索引 1 插入 Blueberry 后: " + fruits);
        // 3. 获取元素
        String firstFruit = fruits.get(0);
        System.out.println("第一个水果是: " + firstFruit);
        // 4. 修改元素
        String oldFruit = fruits.set(2, "Cantaloupe");
        System.out.println("将索引 2 的 " + oldFruit + " 替换为 Cantaloupe 后: " + fruits);
        // 5. 查询判断
        System.out.println("列表是否包含 Banana? " + fruits.contains("Banana"));
        System.out.println("Banana 的索引是: " + fruits.indexOf("Banana"));
        System.out.println("列表大小: " + fruits.size());
        // 6. 删除元素
        fruits.remove("Date"); // 删除特定元素
        System.out.println("删除 Date 后: " + fruits);
        String removedFruit = fruits.remove(0); // 按索引删除
        System.out.println("删除索引 0 的 " + removedFruit + " 后: " + fruits);
        // 7. 遍历
        System.out.println("--- 使用 for-each 遍历 ---");
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
        System.out.println("--- 使用迭代器遍历并删除 ---");
        Iterator<String> iterator = fruits.iterator();
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            if (fruit.startsWith("B")) {
                iterator.remove(); // 安全删除
            }
        }
        System.out.println("删除所有以 B 开头的元素后: " + fruits);
        // 8. 清空
        fruits.clear();
        System.out.println("清空列表后: " + fruits);
        System.out.println("列表是否为空? " + fruits.isEmpty());
    }
}
分享:
扫描分享到社交APP
上一篇
下一篇