文章目录
- Arrays数组
- [ArrayList 可变数组](#ArrayList 可变数组)
-
- [什么是 ArrayList?](#什么是 ArrayList?)
- [ArrayList 的声明与初始化](#ArrayList 的声明与初始化)
-
- [声明 ArrayList](#声明 ArrayList)
- [初始化 ArrayList](#初始化 ArrayList)
- [ArrayList 的常见操作](#ArrayList 的常见操作)
- [遍历 ArrayList](#遍历 ArrayList)
-
- [使用 `for` 循环遍历](#使用
for
循环遍历) - [使用 `foreach` 循环遍历](#使用
foreach
循环遍历) - 使用迭代器遍历
- [使用 `for` 循环遍历](#使用
- [ArrayList 的大小和容量](#ArrayList 的大小和容量)
- 注意事项
Arrays数组
什么是数组?
▪ 一种简单的数据结构
▪ 元素具有相同的数据类型
▪ 一旦创建之后,尺寸保持不变
▪ 元素在内存中连续分布
声明和初始化数组
在 Java 中,要使用数组,首先需要声明和初始化它。
声明数组
声明数组时,你需要指定数组的类型,后面跟着数组名字和一对方括号 [],例如:
java
int[] numbers; // 声明一个整数数组
//声明也可以写成c/c++风格的 int numbers[];
你也可以在声明时为数组分配内存:
java
int[] numbers = new int[5]; // 声明并分配一个包含 5 个整数的数组
初始化数组
初始化数组是为数组分配内存并赋予初值。Java 中有几种初始化数组的方式。
直接初始化
你可以在声明数组的同时为数组分配内存并赋值:
java
int[] numbers = {1, 2, 3, 4, 5}; // 直接初始化一个整数数组
使用循环初始化
使用循环来初始化数组的示例:
java
int[] numbers = new int[5]; // 声明一个包含 5 个整数的数组
for (int i = 0; i < 5; i++) {
numbers[i] = i + 1; // 初始化数组元素
}
访问数组元素
访问数组元素是通过数组的索引来获取数组中的值。在 Java 中,数组的索引从 0 开始,例如:
java
int firstNumber = numbers[0]; // 获取第一个元素的值,即 1
数组的长度
要获取数组的长度(即数组中元素的个数),可以使用数组的 length
属性:
java
int length = numbers.length; // 获取数组 numbers 的长度
这在处理动态数据时非常有用,例如当需要遍历数组时,使用 length
属性可以避免手动维护数组的大小。
遍历数组
遍历数组是逐个访问数组中的所有元素,通常使用循环来实现。在 Java 中,常用的循环有 for
循环和 foreach
循环。
使用 for
循环遍历数组
java
int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]); // 输出数组元素
}
这种方式提供了访问数组索引的灵活性,可以根据需要进行条件控制。
使用 foreach
循环遍历数组
foreach
循环在 Java 5 引入,可以更简洁地遍历数组:(只读的形式遍历,不能操作原数据)
java
for (int number : numbers) {
System.out.println(number); // 输出数组元素
}
使用 foreach
循环可以减少出错的可能性,尤其是在需要遍历大数组时。
数组的常见操作
除了声明、初始化和遍历数组,数组还支持许多常见的操作,如添加元素、删除元素和查找元素。
添加元素
要向数组添加元素,需要创建一个新的数组,将原数组的元素复制到新数组中,并在新数组中添加新元素。示例:
java
int[] numbers = {1, 2, 3, 4, 5};
int[] newArray = new int[numbers.length + 1]; // 创建一个新数组
for (int i = 0; i < numbers.length; i++) {
newArray[i] = numbers[i]; // 复制元素
}
newArray[newArray.length - 1] = 6; // 添加新元素
numbers = newArray; // 更新原数组
删除元素
删除数组中的元素通常也需要创建一个新数组,将原数组中不需要删除的元素复制到新数组中:
java
int[] numbers = {1, 2, 3, 4, 5};
int elementToRemove = 3; // 要删除的元素
int[] newArray = new int[numbers.length - 1];
int newIndex = 0;
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] != elementToRemove) {
newArray[newIndex] = numbers[i];
newIndex++;
}
}
numbers = newArray; // 更新数组
这种方式虽然可以实现功能,但效率较低,尤其是在频繁进行添加或删除操作时。
查找元素
在数组中查找元素,可以使用循环遍历数组,逐个比较每个元素的值:
java
int[] numbers = {1, 2, 3, 4, 5};
int elementToFind = 3; // 要查找的元素
int foundIndex = -1; // 初始化为 -1 表示未找到
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == elementToFind) {
foundIndex = i;
break; // 找到元素后退出循环
}
}
if (foundIndex != -1) {
System.out.println("找到元素 " + elementToFind + ",索引为 " + foundIndex);
} else {
System.out.println("未找到元素 " + elementToFind);
}
对于较大的数组,查找效率可以通过对数组进行排序后使用二分查找算法来提升。
多维数组
除了常见的一维数组,Java 还支持多维数组,即数组的数组。多维数组可以看作是矩阵或表格。
二维数组
二维数组是最常见的多维数组,通常用于表示矩阵。声明和初始化二维数组的示例:
java
int[][] matrix = new int[3][4]; // 声明一个 3x4 的二维整数数组
matrix[0][0] = 1; // 设置第一行第一列的值为 1
int value = matrix[1][2]; // 获取第二行第三列的值
使用二维数组可以方便地表示表格数据,比如学生的成绩表。
不规则二维数组
Java 的二维数组可以是不规则的:
java
int[][] arr = new int[3][]; // 不规则数组
arr[0] = new int[]{1, 2, 3, 4};
arr[1] = new int[]{1, 2};
arr[2] = new int[]{3, 4};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
这种灵活性使得多维数组在处理不同规模数据时非常有效。
数组的性能和内存管理
数组在性能上有显著优势,尤其是在内存连续分配的情况下。数组的大小在创建时固定,Java 虚拟机(JVM)在堆内存中分配数组的内存空间。由于数组是对象,因此它们的引用存储在栈内存中,而实际的数据存储在堆内存中。
内存分配
当声明数组时,JVM 会为其分配足够的内存。例如,创建一个整型数组 new int[5]
时,JVM 会在堆内存中分配 5 个整数的空间。值得注意的是,数组元素的默认值根据类型不同而有所区别:整数默认为 0,布尔值默认为 false,引用类型默认为 null。
性能考虑
虽然数组访问速度快,但它们的大小是固定的。在需要频繁调整大小的场景下,使用 ArrayList 或其他集合类更为合适。Java 的 ArrayList 底层使用数组实现,但提供了动态大小调整的功能。
注意事项
- 数组的大小是固定的,一旦创建,不能更改。
- 数组的索引从 0 开始,访问越界的索引会导致
ArrayIndexOutOfBoundsException
。 - 多维数组的访问需要提供相应数量的索引。
- 对于大规模数据,考虑使用动态数据结构,如链表或集合类。
ArrayList 可变数组
什么是 ArrayList?
在 Java 中,ArrayList
是一个可变长度的数组实现,属于 java.util
包。与普通数组不同,ArrayList
允许动态调整其大小,因此它可以根据需要存储任意数量的元素。ArrayList
主要用于存储对象,可以包含重复元素,并且它们的顺序与插入顺序一致。
ArrayList
是实现 List
接口的一个类,提供了比数组更灵活的数据存储方式,特别适合需要频繁增删元素的场景。
ArrayList 的声明与初始化
要使用 ArrayList
,需要导入 java.util.ArrayList
类。ArrayList
的声明和初始化非常简单。
声明 ArrayList
java
import java.util.ArrayList;
ArrayList<String> list; // 声明一个字符串类型的 ArrayList
初始化 ArrayList
可以在声明时直接初始化:
java
ArrayList<String> list = new ArrayList<>(); // 初始化一个空的 ArrayList
你也可以使用指定初始容量的构造函数:
java
ArrayList<Integer> numbers = new ArrayList<>(10); // 初始化一个容量为 10 的 ArrayList
ArrayList 的常见操作
添加元素
使用 add()
方法向 ArrayList
中添加元素:
java
list.add("Hello"); // 添加字符串 "Hello"
list.add("World"); // 添加字符串 "World"
添加元素时,可以在指定索引位置插入元素:
java
list.add(1, "Java"); // 在索引 1 处插入 "Java"
访问元素
可以使用 get()
方法通过索引访问元素:
java
String firstElement = list.get(0); // 获取第一个元素
修改元素
使用 set()
方法可以修改指定索引位置的元素:
java
list.set(1, "Programming"); // 将索引 1 的元素修改为 "Programming"
删除元素
删除元素可以使用 remove()
方法,通过元素值或索引进行删除:
java
list.remove("Hello"); // 删除元素 "Hello"
list.remove(0); // 删除索引 0 处的元素
查找元素
使用 contains()
方法检查 ArrayList
中是否包含特定元素:
java
boolean hasWorld = list.contains("World"); // 检查是否包含 "World"
使用 indexOf()
方法可以找到元素的索引:
java
int index = list.indexOf("Programming"); // 查找 "Programming" 的索引
遍历 ArrayList
遍历 ArrayList
的方式有多种,最常用的包括 for
循环、foreach
循环和迭代器。
使用 for
循环遍历
java
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); // 输出每个元素
}
使用 foreach
循环遍历
foreach
循环可以更简洁地遍历元素:
java
for (String item : list) {
System.out.println(item); // 输出每个元素
}
使用迭代器遍历
java
import java.util.Iterator;
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next()); // 输出每个元素
}
ArrayList 的大小和容量
获取大小
使用 size()
方法获取 ArrayList
中元素的数量:
java
int size = list.size(); // 获取当前 ArrayList 的大小
动态扩展
ArrayList
可以动态扩展其容量。当添加新元素时,如果当前容量不足,ArrayList
会自动增加容量,通常是原来容量的 1.5 倍。这种特性使得 ArrayList
非常灵活。
注意事项
ArrayList
不能存储基本数据类型,但可以存储其包装类,如Integer
、Double
等。- 在多线程环境下,使用
ArrayList
时要注意线程安全问题,通常建议使用Collections.synchronizedList()
方法将其转化为线程安全的列表。 - 如果需要频繁插入和删除操作,考虑使用
LinkedList
,因为其在链表中插入和删除元素的效率更高。