Java容器之一——ArrayList

ArrayList 是 Java 集合框架(Java Collections Framework)中的一个重要类,它实现了 List 接口,并使用动态数组作为其数据结构。由于 ArrayList 是基于数组实现的,所以它支持快速的随机访问元素,但是在列表的中间插入或删除元素时可能会相对较慢,因为可能需要进行元素的移动。

下面我们来详细解析 ArrayList:

1. 初始化

ArrayList 可以有多种初始化方式:

java 复制代码
// 创建一个空的 ArrayList
ArrayList<String> list1 = new ArrayList<>();

// 创建一个带有初始容量的 ArrayList
ArrayList<String> list2 = new ArrayList<>(10);

// 创建一个包含初始元素的 ArrayList
ArrayList<String> list3 = new ArrayList<>(Arrays.asList("a", "b", "c"));

2. 主要方法

ArrayList 提供了一系列方法来操作其元素:

  • 添加元素:

    • add(E e): 将指定的元素添加到此列表的末尾。
    • add(int index, E element): 在此列表中的指定位置插入指定的元素。
    • addAll(Collection<? extends E> c): 将指定集合中的所有元素添加到此列表的末尾。
  • 删除元素:

    • remove(int index): 移除列表中指定位置的元素。
    • remove(Object o): 移除列表中首次出现的指定元素。
    • clear(): 移除列表中的所有元素。
  • 获取元素:

    • get(int index): 返回列表中指定位置的元素。
    • subList(int fromIndex, int toIndex): 返回列表中指定的 fromIndex(包括)和 toIndex(不包括)之间的部分视图。
  • 修改元素:

    • set(int index, E element): 用指定的元素替换此列表中指定位置上的元素。
  • 查找元素:

    • indexOf(Object o): 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
    • lastIndexOf(Object o): 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
    • contains(Object o): 如果此列表包含指定的元素,则返回 true。
  • 列表的大小:

    • size(): 返回此列表中的元素数。
    • isEmpty(): 如果此列表不包含元素,则返回 true。
  • 其他操作:

    • ensureCapacity(int minCapacity): 增加此 ArrayList 实例的容量,以确保它至少可以容纳由最小容量参数指定的元素数,而不会进行大小调整。
    • trimToSize(): 将此 ArrayList 实例的容量调整为列表的当前大小。

3. 容量和大小

ArrayList 的容量(Capacity)是其底层数组的大小。ArrayList 的大小(Size)是其当前包含的元素数量。当添加元素时,如果当前容量不足以容纳新元素,ArrayList 会自动进行扩容,这通常涉及创建一个新的更大的数组,并将旧数组的元素复制到新数组中。

4. 线程安全性

ArrayList 不是线程安全的。如果多个线程同时修改 ArrayList,则必须外部同步。Java 提供了 Collections.synchronizedList 方法来创建一个线程安全的 List。另外,Java 并发包(java.util.concurrent)中的 CopyOnWriteArrayList 类提供了线程安全的变体,它适用于读多写少的场景。

5. 性能

由于 ArrayList 是基于数组实现的,所以在随机访问元素时性能很好,时间复杂度为 O(1)。但在列表的中间插入或删除元素时,可能需要移动元素,时间复杂度为 O(n)。如果需要频繁在列表中间进行插入或删除操作,可以考虑使用 LinkedList。

示例

下面是一个简单的 ArrayList 使用示例,展示了如何创建 ArrayList 实例、添加元素、遍历元素以及执行一些基本操作。

java 复制代码
import java.util.ArrayList;

public class ArrayListSimpleExample {
    public static void main(String[] args) {
        // 创建一个 ArrayList 实例,用于存储 String 类型的元素
        ArrayList<String> fruits = new ArrayList<>();

        // 向 ArrayList 中添加元素
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Cherry");

        // 输出 ArrayList 的当前大小
        System.out.println("Size of fruits list: " + fruits.size());

        // 检查 ArrayList 是否包含某个元素
        boolean containsBanana = fruits.contains("Banana");
        System.out.println("Does list contain Banana? " + containsBanana);

        // 遍历 ArrayList 并输出每个元素
        for (String fruit : fruits) {
            System.out.println(fruit);
        }

        // 使用索引访问和修改 ArrayList 中的元素
        String firstFruit = fruits.get(0);
        System.out.println("First fruit: " + firstFruit);

        fruits.set(0, "Apricot"); // 修改第一个元素为 "Apricot"

        // 再次遍历 ArrayList 查看修改后的元素
        System.out.println("After modification:");
        for (String fruit : fruits) {
            System.out.println(fruit);
        }

        // 在特定位置插入新元素
        fruits.add(1, "Blueberry"); // 在索引 1 的位置插入 "Blueberry"

        // 删除 ArrayList 中的元素
        fruits.remove("Cherry"); // 删除第一个出现的 "Cherry"

        // 再次输出 ArrayList 的内容
        System.out.println("After insertion and deletion:");
        for (String fruit : fruits) {
            System.out.println(fruit);
        }
    }
}

这个示例程序做了以下几件事情:

  1. 创建了一个 ArrayList 实例 fruits,用于存储 String 类型的元素。
  2. 使用 add() 方法向 ArrayList 中添加了三个元素。
  3. 使用 size() 方法输出了 ArrayList 的当前大小。
  4. 使用 contains() 方法检查 ArrayList 是否包含某个元素,并输出结果。
  5. 使用 for-each循环遍历 ArrayList 并输出每个元素。
  6. 使用 get() 方法通过索引访问 ArrayList 中的第一个元素,并输出。
  7. 使用 set() 方法修改 ArrayList 中第一个元素的值。
  8. 再次遍历 ArrayList 查看修改后的元素。
  9. 使用 add() 方法在特定位置插入一个新元素。
  10. 使用 remove() 方法删除 ArrayList 中的一个元素。
  11. 再次遍历 ArrayList 查看插入和删除操作后的元素。

运行这个程序,你会在控制台上看到以下输出(假设没有其他输出):

yaml 复制代码
Size of fruits list: 3
Does list contain Banana? true
Apple
Banana
Cherry
First fruit: Apple
After modification:
Apricot
Banana
Cherry
After insertion and deletion:
Apricot
Blueberry
Banana

这个示例展示了 ArrayList 的基本用法,包括元素的添加、访问、修改、删除以及遍历。在实际开发中,你可以根据需求使用更多的 ArrayList 方法和特性。

相关推荐
小蒜学长1 小时前
编程语言在线学习平台的设计与实现(代码+数据库+LW)
java·spring boot·后端·编程语言在线学习平台·在线编码
步行cgn2 小时前
Spring MVC 执行流程详解:一次请求的完整旅程
java·spring·mvc
增量星球2 小时前
Spring AI 2.0 Tool Calling 到底怎么跑起来的:从 @Tool 到两次模型调用
java·agent·springai·ai coding
步行cgn2 小时前
Spring MVC 九大核心角色详解:请求处理链路中的每一个关键组件
java·spring·mvc
智恒百亿2 小时前
一台 5090 八卡服务器怎么分给一个团队用?多模型多任务的显存分配实战
java·大数据·人工智能
瑞码空间2 小时前
面向接口编程与开闭原则在模拟 JDBC 驱动中的应用
java·jdbc
Félix2513 小时前
Nacos学习笔记(SpringBoot/SpringCloud)
java·spring boot·spring
文丑颜不良啊3 小时前
LeetCode1581~1600题目解析
java·leetcode
香蕉大香蕉(06敬畏市场)3 小时前
MySQL 单点详解(06)
java·数据库·mysql·博客·实习
lqbzlll3 小时前
Spring Boot 开启虚拟线程后接口反而变慢了?4 个排查方向和对应修法
java·spring boot·后端