杰瑞科技汇

java arraylist 用法

什么是 ArrayList?

ArrayList 是一个动态数组的实现,它位于 java.util 包下,实现了 List 接口,相比于 Java 中固定长度的数组,ArrayList 的最大优势在于其大小可变,可以根据需要自动扩容。

java arraylist 用法-图1
(图片来源网络,侵删)

核心特点:

  • 动态大小:可以随时添加或删除元素,而无需关心其容量。
  • 有序性:元素按照插入的顺序存储,并可以通过索引(0-based)访问。
  • 允许重复元素:可以存储多个 null 值。
  • 非线程安全:在多线程环境下,如果多个线程同时修改一个 ArrayList,可能会导致数据不一致,如果需要线程安全,可以使用 VectorCollections.synchronizedList() 包装的 ArrayList

如何创建 ArrayList?

主要有三种方式来创建 ArrayList 对象。

创建一个空的 ArrayList

这种方式最常用,创建一个可以存储 String 类型元素的列表。

import java.util.ArrayList;
import java.util.List;
// 使用泛型 <String> 来指定列表中只能存储 String 类型的对象
List<String> stringList = new ArrayList<>();

创建一个指定初始容量的 ArrayList

如果你预先知道列表大概要存储多少个元素,可以指定初始容量以减少扩容操作,提高性能。

java arraylist 用法-图2
(图片来源网络,侵删)
// 创建一个初始容量为 10 的 ArrayList
List<String> stringListWithCapacity = new ArrayList<>(10);

使用另一个集合来初始化 ArrayList

你可以用已有的 List, Set 或其他集合来创建一个新的 ArrayList

List<String> existingList = new ArrayList<>();
existingList.add("Apple");
existingList.add("Banana");
// 使用 existingList 初始化一个新的 ArrayList
List<String> newList = new ArrayList<>(existingList);
System.out.println(newList); // 输出: [Apple, Banana]

常用方法详解

下面是 ArrayList 最核心的一些方法,并附有示例代码。

1 添加元素

方法 描述 示例
add(E e) 在列表的末尾添加一个元素。 list.add("Cat");
add(int index, E e) 在列表的指定 index 位置插入一个元素。 list.add(1, "Dog");
List<String> animals = new ArrayList<>();
// 1. add(E e) - 在末尾添加
animals.add("Lion");
animals.add("Tiger");
System.out.println("添加后: " + animals); // 输出: [Lion, Tiger]
// 2. add(int index, E e) - 在指定位置插入
animals.add(1, "Elephant"); // 在索引 1 的位置插入 "Elephant"
System.out.println("插入后: " + animals); // 输出: [Lion, Elephant, Tiger]

2 获取元素

方法 描述 示例
get(int index) 返回列表中指定 index 位置的元素。 String name = list.get(0);
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
// get(int index)
String firstFruit = fruits.get(0); // 获取索引为 0 的元素
System.out.println("第一个水果是: " + firstFruit); // 输出: 第一个水果是: Apple

3 修改元素

方法 描述 示例
set(int index, E e) 用指定的元素替换列表中指定 index 位置的元素。 list.set(0, "New Apple");
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
System.out.println("修改前: " + fruits); // 输出: [Apple, Banana]
// set(int index, E e)
fruits.set(1, "Orange"); // 将索引 1 的 "Banana" 替换为 "Orange"
System.out.println("修改后: " + fruits); // 输出: [Apple, Orange]

4 删除元素

方法 描述 示例
remove(int index) 移除列表中指定 index 位置的元素,并返回被移除的元素。 list.remove(0);
remove(Object o) 移除列表中第一个出现的指定元素 o,如果元素存在,返回 true,否则返回 false list.remove("Apple");
List<String> pets = new ArrayList<>();
pets.add("Dog");
pets.add("Cat");
pets.add("Parrot");
pets.add("Cat"); // 添加一个重复的 "Cat"
System.out.println("删除前: " + pets); // 输出: [Dog, Cat, Parrot, Cat]
// remove(int index)
String removedPet = pets.remove(0); // 删除索引为 0 的 "Dog"
System.out.println("被删除的宠物是: " + removedPet); // 输出: 被删除的宠物是: Dog
System.out.println("删除索引0后: " + pets); // 输出: [Cat, Parrot, Cat]
// remove(Object o)
boolean isRemoved = pets.remove("Cat"); // 删除第一个出现的 "Cat"
System.out.println("是否成功删除 'Cat': " + isRemoved); // 输出: true
System.out.println("删除元素后: " + pets); // 输出: [Parrot, Cat]

5 查询与判断

方法 描述 示例
size() 返回列表中的元素个数(不是容量)。 int count = list.size();
isEmpty() 如果列表不包含元素,则返回 true boolean empty = list.isEmpty();
contains(Object o) 如果列表中包含指定的元素,则返回 true boolean hasCat = list.contains("Cat");
indexOf(Object o) 返回此列表中第一次出现的指定元素的索引;如果列表不包含该元素,则返回 -1。 int index = list.indexOf("Cat");
lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引。 int lastIndex = list.lastIndexOf("Cat");
List<String> colors = new ArrayList<>();
colors.add("Red");
colors.add("Green");
colors.add("Blue");
colors.add("Green");
System.out.println("颜色列表: " + colors);
// size()
System.out.println("列表大小: " + colors.size()); // 输出: 4
// isEmpty()
System.out.println("列表是否为空: " + colors.isEmpty()); // 输出: false
// contains(Object o)
System.out.println("列表是否包含 'Green': " + colors.contains("Green")); // 输出: true
// indexOf(Object o)
System.out.println("'Green' 第一次出现的索引: " + colors.indexOf("Green")); // 输出: 1
// lastIndexOf(Object o)
System.out.println("'Green' 最后一次出现的索引: " + colors.lastIndexOf("Green")); // 输出: 3

6 遍历 ArrayList

有四种主要的方式遍历 ArrayList

for 循环(通过索引) 最传统的方式,适合需要通过索引操作元素的场景。

java arraylist 用法-图3
(图片来源网络,侵删)
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (int i = 0; i < names.size(); i++) {
    System.out.println("索引 " + i + ": " + names.get(i));
}

for-each 循环(增强 for 循环) 最简洁、最推荐的方式,适用于只需要读取每个元素的场景。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) {
    System.out.println("名字: " + name);
}

使用 Iterator(迭代器) 可以在遍历时安全地删除元素,避免 ConcurrentModificationException

List<String> names = new ArrayList<>(Arrays.asList("Alice", "Bob", "Charlie"));
Iterator<String> iterator = names.iterator();
while (iterator.hasNext()) {
    String name = iterator.next();
    if ("Bob".equals(name)) {
        iterator.remove(); // 使用迭代器的 remove 方法安全删除
    }
}
System.out.println("删除 Bob 后: " + names); // 输出: [Alice, Charlie]

使用 Java 8+ 的 Stream API 功能最强大,可以进行链式操作,如过滤、排序、映射等。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
// 1. 简单遍历
names.stream().forEach(name -> System.out.println("Stream 遍历: " + name));
// 2. 过滤并打印长度大于 4 的名字
System.out.println("\n名字长度大于 4 的:");
names.stream()
     .filter(name -> name.length() > 4)
     .forEach(System.out::println);
// 输出:
// 名字长度大于 4 的:
// Alice
// Charlie
// David

7 其他重要方法

方法 描述 示例
clear() 移除列表中的所有元素。 list.clear();
toArray() 将列表转换为一个数组。 Object[] array = list.toArray();
List<String> temp = new ArrayList<>();
temp.add("One");
temp.add("Two");
System.out.println("清空前: " + temp); // 输出: [One, Two]
temp.clear();
System.out.println("清空后: " + temp); // 输出: []
System.out.println("列表是否为空: " + temp.isEmpty()); // 输出: true
// toArray()
List<String> numbers = Arrays.asList("1", "2", "3");
String[] stringArray = numbers.toArray(new String[0]);
System.out.println("转换后的数组: " + Arrays.toString(stringArray)); // 输出: [1, 2, 3]

ArrayList vs. 固定数组

特性 ArrayList 固定数组 (String[])
大小 动态可变 固定不变
性能 添加元素可能触发扩容,有性能开销,随机访问(get)性能高,接近 O(1)。 创建后大小固定,没有扩容开销,随机访问性能高,O(1)。
功能 提供丰富的 API,如 add, remove, size, contains 等。 功能有限,需要自己实现或借助工具类。
使用场景 绝大多数情况,特别是元素数量不确定或需要频繁增删的场景。 元素数量确定且不变的场景,或者对性能要求极高的底层代码。

最佳实践与注意事项

  1. 始终使用泛型:像 List<String> 而不是 List,这样可以确保类型安全,避免在运行时出现 ClassCastException
  2. 避免在循环中删除元素:如果你想在遍历 ArrayList 时删除多个元素,不要使用 for 循环和 list.remove(index) 的组合,因为这会导致索引错乱,推荐使用 Iteratorremove() 方法。
  3. 初始化容量:如果你能预估 ArrayList 的大致大小,在创建时指定一个合理的初始容量(如 new ArrayList<>(1000)),可以避免多次扩容,提高性能。
  4. 理解 size()capacitysize() 是当前元素的个数,而 capacity 是底层数组的长度。ArrayListsize 超过 capacity 时会自动扩容(通常是扩容为原来的 1.5 倍)。
  5. 线程安全ArrayList 不是线程安全的,如果在多线程环境下共享一个 ArrayList 实例,必须进行同步处理,简单的方法是使用 Collections.synchronizedList(new ArrayList<>())
// 线程安全的 ArrayList
List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());

完整示例代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ArrayListExample {
    public static void main(String[] args) {
        // 1. 创建 ArrayList
        List<String> fruits = new ArrayList<>();
        System.out.println("初始列表: " + fruits);
        // 2. 添加元素
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Cherry");
        System.out.println("添加后: " + fruits);
        // 3. 在指定位置插入
        fruits.add(1, "Blueberry");
        System.out.println("插入后: " + fruits);
        // 4. 获取元素
        String firstFruit = fruits.get(0);
        System.out.println("第一个水果: " + firstFruit);
        // 5. 修改元素
        fruits.set(2, "Blackberry");
        System.out.println("修改后: " + fruits);
        // 6. 查询
        System.out.println("列表大小: " + fruits.size());
        System.out.println("是否包含 'Apple': " + fruits.contains("Apple"));
        System.out.println("'Banana' 的索引: " + fruits.indexOf("Banana"));
        // 7. 删除元素
        fruits.remove("Blueberry"); // 删除特定元素
        System.out.println("删除 'Blueberry' 后: " + fruits);
        String removedFruit = fruits.remove(0); // 删除指定索引的元素
        System.out.println("被删除的元素: " + removedFruit);
        System.out.println("删除索引0后: " + fruits);
        // 8. 遍历 ArrayList
        System.out.println("\n--- 遍历方式 ---");
        // a. for-each 循环 (推荐)
        System.out.println("使用 for-each:");
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
        // b. 使用 Iterator (安全删除)
        System.out.println("\n使用 Iterator 删除 'Cherry':");
        Iterator<String> iterator = fruits.iterator();
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            if ("Cherry".equals(fruit)) {
                iterator.remove();
            }
        }
        System.out.println("删除后: " + fruits);
        // 9. 清空列表
        fruits.clear();
        System.out.println("\n清空后列表: " + fruits);
        System.out.println("列表是否为空: " + fruits.isEmpty());
    }
}

希望这份详细的指南能帮助你全面掌握 Java ArrayList 的用法!

分享:
扫描分享到社交APP
上一篇
下一篇