在 Java 中,集合(Collection) 和 数组(Array) 都是用来存储多个元素的数据结构,但它们在设计目标、功能特性、使用方式和性能表现上有本质区别。
1. 核心区别概览
| 特性 | 集合(Collection) | 数组(Array) |
|---|---|---|
| 长度 | 动态可变(如ArrayList自动扩容) | 创建后固定不变 |
| 类型支持 | 只能存储对象引用(需要用包装类存储基础类型) | 可直接存储基本类型int[],或者引用类型 |
| 泛型 | 完全支持(编译期间类型安全) | 不支持泛型;引用类型数组有运行时类型检查风险 |
| API丰富度 | 丰富(add、remove、contains等) | 仅有.length |
| 内存 | 多数非连续(如 LinkedList),或逻辑连续物理分散(如 ArrayList 底层是数组,但扩容时重新分配内存);内存开销大 | 连续内存地址,访问速度快,内存开销极低 |
| 存储维度 | 仅一维,多维需要嵌套(如:List<List>) | 支持多维(如 int[][] arr 二维数组) |
| 是否属于java对象体系 | 是普通对象,Java 集合框架(Collection Framework)是普通 Java 类 / 接口的封装,完全遵循对象体系的规则 | 是java原生对象,Java 数组是语言级别的原生对象,而非普通类的实例,但仍完全归属对象体系 |
1.1 长度可变性
public class ArrayListTest {
public static void main(String[] args) {
// 实例化ArrayList容器
List<Integer> list = new ArrayList<>();
list.add(1);
System.out.println(list);
String[] arr = new String[2];
arr[2] = "c"; // 报错, 要拓展数组必须新建并赋值数组
System.out.println(arr);
}
}
1.2 存储基本类型
public class ArrayListTest {
public static void main(String[] args) {
// 实例化ArrayList容器
List<int> list1 = new ArrayList<>(); // 编译错误
List<Integer> list2 = new ArrayList<>(); // 必须要用包装类
int[] nums = {1, 2, 3}; // 数组直接支持
}
}
1.3 类型安全
public class ArrayListTest {
public static void main(String[] args) {
// 集合 + 泛型
List<String> list = new ArrayList<>();
list.add(1); // 编译报错
// 数组不可以用泛型
Object[] objArr = new String[2];
objArr[0] = 123; // 报错,ArrayStoreException(数组存储异常)
}
}