杰瑞科技汇

ArrayList和数组有何区别?

  1. 什么是数组?
  2. 什么是 ArrayList
  3. ArrayList 与数组的核心区别
  4. 代码示例:如何使用数组和 ArrayList
  5. 何时使用数组,何时使用 ArrayList

什么是数组?

数组是 Java 中最基本的一种数据结构,你可以把它想象成一个固定大小的容器,用来存放相同类型的元素。

ArrayList和数组有何区别?-图1
(图片来源网络,侵删)

核心特点:

  • 固定大小:数组一旦被创建,其大小(能存放多少个元素)就不能改变,如果你需要添加更多元素,就必须创建一个新数组,并把旧数组的内容复制过去。
  • 类型相同:一个数组里只能存放一种数据类型(全是 int,或全是 String)。
  • 索引访问:通过索引(从 0 开始)来访问和修改元素,速度非常快。

如何声明和初始化一个数组:

// 1. 声明一个 int 类型的数组,名为 myArray
int[] myArray;
// 2. 创建一个可以存放 5 个 int 元素的空间
myArray = new int[5];
// 也可以一步完成
String[] names = new String[3]; // 创建一个可以存放 3 个 String 的数组
// 3. 赋值
myArray[0] = 10;
myArray[1] = 20;
myArray[2] = 30;
myArray[3] = 40;
myArray[4] = 50;
// 4. 访问元素
int firstElement = myArray[0]; // firstElement 的值是 10

什么是 ArrayList

ArrayList 是 Java 集合框架 (java.util) 中的一部分,你可以把它想象成一个动态的、可自动扩容的数组,它内部实际上就是用数组来实现的,但为你封装好了所有复杂的操作。

核心特点:

ArrayList和数组有何区别?-图2
(图片来源网络,侵删)
  • 动态大小ArrayList 的大小可以随时改变,当你添加的元素超过了当前容量时,它会自动在内部创建一个更大的数组,并将所有元素复制过去,这个过程对用户是透明的。
  • 可以存放对象ArrayList 只能存放对象类型,不能存放基本数据类型(如 int, char 等),但你可以使用它们的包装类(如 Integer, Character)。
  • 丰富的 API:提供了很多有用的方法,如 add(), get(), remove(), size() 等,使用非常方便。

如何声明和使用一个 ArrayList

import java.util.ArrayList; // 别忘了导入包!
// 1. 创建一个可以存放 String 对象的 ArrayList
ArrayList<String> namesList = new ArrayList<>();
// 2. 添加元素 (add 方法)
namesList.add("Alice");
namesList.add("Bob");
namesList.add("Charlie");
// 3. 在指定位置插入元素
namesList.add(1, "David"); // 在索引 1 的位置插入 "David"
// 4. 获取元素 (get 方法)
String secondName = namesList.get(1); // secondName 的值是 "David"
// 5. 获取大小 (size 方法)
int size = namesList.size(); // size 的值是 4
// 6. 删除元素
namesList.remove(0); // 删除索引 0 的元素 "Alice"
namesList.remove("Bob"); // 删除值为 "Bob" 的元素
// 7. 遍历 ArrayList
for (String name : namesList) {
    System.out.println(name);
}

ArrayList 与数组的核心区别

特性 数组 ArrayList
大小 固定,创建后不能改变。 动态,可以随时添加或删除元素,自动扩容/缩容。
数据类型 可以是基本数据类型 (int[]),也可以是对象 (String[])。 只能是对象类型,存放基本类型时需使用其包装类 (ArrayList<Integer>)。
性能 访问速度快 (O(1)),增删元素慢(因为涉及移动元素和创建新数组)。 访问速度稍慢(因为有自动拆装箱的潜在开销,但也是 O(1)),增删元素更方便,性能也较好。
功能/方法 功能非常有限,只有一个 length 属性。 提供了非常丰富的方法,如 add(), remove(), size(), contains() 等。
语法 语法更简洁,直接使用 [] 访问。 语法稍显冗长,需要声明泛型类型(如 <String>)。
内存 内存是连续分配的,效率高。 有一定的额外内存开销,因为需要维护内部数组的容量和大小。

代码示例:一个简单的对比

假设我们要存储一个班级里学生的名字,并添加一个新同学。

使用数组:

public class ArrayExample {
    public static void main(String[] args) {
        // 1. 创建一个固定大小的数组
        String[] students = new String[3];
        students[0] = "张三";
        students[1] = "李四";
        students[2] = "王五";
        System.out.println("原始数组: " + java.util.Arrays.toString(students));
        // 2. 添加一个新同学 "赵六"
        // 数组大小固定,无法直接添加!必须创建一个新数组。
        String[] newStudents = new String[students.length + 1];
        // 复制旧数组元素到新数组
        System.arraycopy(students, 0, newStudents, 0, students.length);
        // 添加新元素
        newStudents[newStudents.length - 1] = "赵六";
        students = newStudents; // 让原数组引用指向新数组
        System.out.println("添加后的数组: " + java.util.Arrays.toString(students));
    }
}

使用 ArrayList

import java.util.ArrayList;
public class ArrayListExample {
    public static void main(String[] args) {
        // 1. 创建一个 ArrayList
        ArrayList<String> students = new ArrayList<>();
        students.add("张三");
        students.add("李四");
        students.add("王五");
        System.out.println("原始 ArrayList: " + students);
        // 2. 添加一个新同学 "赵六"
        // 非常简单!
        students.add("赵六");
        System.out.println("添加后的 ArrayList: " + students);
    }
}

从上面的例子可以清晰地看出,ArrayList 在处理动态数据时是多么方便。


何时使用数组,何时使用 ArrayList

这是一个非常常见且重要的面试问题,以下是简单的判断准则:

优先使用 ArrayList 的情况:

  1. 当你不知道需要存储多少个元素时,这是最常见的情况,ArrayList 的动态扩容特性完美解决了这个问题。
  2. 当你需要频繁地添加或删除元素时ArrayList 提供了简单高效的方法。
  3. 当你需要使用集合框架提供的强大功能时contains() 检查元素是否存在,remove() 删除特定元素等。
  4. 在绝大多数日常业务开发中ArrayList 是默认选择,因为它更灵活、更安全。

考虑使用数组 的情况:

  1. 当你确定数据量的大小永远不会改变时,表示一年的12个月,一周的7天,使用数组更高效,也更节省内存。
  2. 当你追求极致的性能时,特别是在处理大量数据且主要操作是随机访问(通过索引读取)时,数组的访问速度理论上比 ArrayList 快一点点,因为少了方法调用的开销。
  3. 当你需要与 Java 的某些底层API交互时,这些API要求参数必须是数组类型(main 方法的 String[] args)。
  4. 在多维数组场景下,如果维度固定,使用原生数组(如 int[][])可能比 ArrayList<ArrayList<Integer>> 更直观。

数组 ArrayList
一句话总结 一个静态的、固定大小的容器。 一个动态的、可自动扩容的容器。
学习建议 理解其基本概念和局限性。 作为日常开发的首选,熟练掌握其API。

ArrayList 是对数组的强大封装和升级,对于绝大多数 Java 开发场景,你都应该优先使用 ArrayList,只有在少数特定情况下(如数据量固定、追求极致性能),才需要直接使用原始数组,理解它们之间的区别和联系,是成为一名合格 Java 程序员的重要一步。

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