Java数组:Arrays 和 ArrayList 的基本操作

Arrays数组

什么是数组?

▪ 一种简单的数据结构
▪ 元素具有相同的数据类型
▪ 一旦创建之后,尺寸保持不变
▪ 元素在内存中连续分布

声明和初始化数组

在 Java 中,要使用数组,首先需要声明和初始化它。

声明数组

声明数组时,你需要指定数组的类型,后面跟着数组名字和一对方括号 [],例如:

int[] numbers; // 声明一个整数数组
//声明也可以写成c/c++风格的  int numbers[];

你也可以在声明时为数组分配内存:

int[] numbers = new int[5]; // 声明并分配一个包含 5 个整数的数组

初始化数组

初始化数组是为数组分配内存并赋予初值。Java 中有几种初始化数组的方式。

直接初始化

你可以在声明数组的同时为数组分配内存并赋值:

int[] numbers = {1, 2, 3, 4, 5}; // 直接初始化一个整数数组
使用循环初始化

使用循环来初始化数组的示例:

int[] numbers = new int[5]; // 声明一个包含 5 个整数的数组
for (int i = 0; i < 5; i++) {
    numbers[i] = i + 1; // 初始化数组元素
}

访问数组元素

访问数组元素是通过数组的索引来获取数组中的值。在 Java 中,数组的索引从 0 开始,例如:

int firstNumber = numbers[0]; // 获取第一个元素的值,即 1

数组的长度

要获取数组的长度(即数组中元素的个数),可以使用数组的 length 属性:

int length = numbers.length; // 获取数组 numbers 的长度

这在处理动态数据时非常有用,例如当需要遍历数组时,使用 length 属性可以避免手动维护数组的大小。

遍历数组

遍历数组是逐个访问数组中的所有元素,通常使用循环来实现。在 Java 中,常用的循环有 for 循环和 foreach 循环。

使用 for 循环遍历数组

int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]); // 输出数组元素
}

这种方式提供了访问数组索引的灵活性,可以根据需要进行条件控制。

使用 foreach 循环遍历数组

foreach 循环在 Java 5 引入,可以更简洁地遍历数组:(只读的形式遍历,不能操作原数据)

for (int number : numbers) {
    System.out.println(number); // 输出数组元素
}

使用 foreach 循环可以减少出错的可能性,尤其是在需要遍历大数组时。

数组的常见操作

除了声明、初始化和遍历数组,数组还支持许多常见的操作,如添加元素、删除元素和查找元素。

添加元素

要向数组添加元素,需要创建一个新的数组,将原数组的元素复制到新数组中,并在新数组中添加新元素。示例:

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; // 更新原数组

删除元素

删除数组中的元素通常也需要创建一个新数组,将原数组中不需要删除的元素复制到新数组中:

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; // 更新数组

这种方式虽然可以实现功能,但效率较低,尤其是在频繁进行添加或删除操作时。

查找元素

在数组中查找元素,可以使用循环遍历数组,逐个比较每个元素的值:

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 还支持多维数组,即数组的数组。多维数组可以看作是矩阵或表格。

二维数组

二维数组是最常见的多维数组,通常用于表示矩阵。声明和初始化二维数组的示例:

int[][] matrix = new int[3][4]; // 声明一个 3x4 的二维整数数组
matrix[0][0] = 1; // 设置第一行第一列的值为 1
int value = matrix[1][2]; // 获取第二行第三列的值

使用二维数组可以方便地表示表格数据,比如学生的成绩表。

不规则二维数组

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

import java.util.ArrayList;

ArrayList<String> list; // 声明一个字符串类型的 ArrayList

初始化 ArrayList

可以在声明时直接初始化:

ArrayList<String> list = new ArrayList<>(); // 初始化一个空的 ArrayList

你也可以使用指定初始容量的构造函数:

ArrayList<Integer> numbers = new ArrayList<>(10); // 初始化一个容量为 10 的 ArrayList

ArrayList 的常见操作

添加元素

使用 add() 方法向 ArrayList 中添加元素:

list.add("Hello"); // 添加字符串 "Hello"
list.add("World"); // 添加字符串 "World"

添加元素时,可以在指定索引位置插入元素:

list.add(1, "Java"); // 在索引 1 处插入 "Java"

访问元素

可以使用 get() 方法通过索引访问元素:

String firstElement = list.get(0); // 获取第一个元素

修改元素

使用 set() 方法可以修改指定索引位置的元素:

list.set(1, "Programming"); // 将索引 1 的元素修改为 "Programming"

删除元素

删除元素可以使用 remove() 方法,通过元素值或索引进行删除:

list.remove("Hello"); // 删除元素 "Hello"
list.remove(0); // 删除索引 0 处的元素

查找元素

使用 contains() 方法检查 ArrayList 中是否包含特定元素:

boolean hasWorld = list.contains("World"); // 检查是否包含 "World"

使用 indexOf() 方法可以找到元素的索引:

int index = list.indexOf("Programming"); // 查找 "Programming" 的索引

遍历 ArrayList

遍历 ArrayList 的方式有多种,最常用的包括 for 循环、foreach 循环和迭代器。

使用 for 循环遍历

for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i)); // 输出每个元素
}

使用 foreach 循环遍历

foreach 循环可以更简洁地遍历元素:

for (String item : list) {
    System.out.println(item); // 输出每个元素
}

使用迭代器遍历

import java.util.Iterator;

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next()); // 输出每个元素
}

ArrayList 的大小和容量

获取大小

使用 size() 方法获取 ArrayList 中元素的数量:

int size = list.size(); // 获取当前 ArrayList 的大小

动态扩展

ArrayList 可以动态扩展其容量。当添加新元素时,如果当前容量不足,ArrayList 会自动增加容量,通常是原来容量的 1.5 倍。这种特性使得 ArrayList 非常灵活。

注意事项

  • ArrayList 不能存储基本数据类型,但可以存储其包装类,如 IntegerDouble 等。
  • 在多线程环境下,使用 ArrayList 时要注意线程安全问题,通常建议使用 Collections.synchronizedList() 方法将其转化为线程安全的列表。
  • 如果需要频繁插入和删除操作,考虑使用 LinkedList,因为其在链表中插入和删除元素的效率更高。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值