1、数组的声明和初始化
1.1.仅声明数组
数组的声明涉及到指定数组的类型以及数组的名称。数组的声明格式遵循固定格式。在这种情况下,数组变量被声明了,但还没有分配内存空间。这些数组变量只是引用类型变量,它们此时没有任何内存空间与之关联,尝试访问这些变量将导致NullPointerException
。
type[] arrayName; 或者type arrayName[];说明:
type
:数组元素的数据类型,可以是Java的基本数据类型(如int
、double
等)或任何引用类型(如String
、Object
等)。arrayName
:数组的名称,遵循Java的标识符命名规则[]
:是数组标识,标识这是一个数组,可以在数据类型后,也可以在变量名后面。// 声明一个整型数组 int[] intArray; // 声明一个字符串数组 String strArray[]; // 声明一个双精度浮点型数组 double[] doubleArray;
1.2.数组声明并初始化
数组的初始化是为数组分配内存空间并设置初始值的过程。Java提供了几种不同的数组初始化方式。
1.2.1.使用new关键字(指定大小)
type[] arrayName = new type[size];
size
:数组的长度,即数组将存储的元素数量。- 这种方式初始化数组时,所有元素都会被自动设置为其类型的默认值:数值类型为0,布尔类型为
false
,对象引用类型为null
。1.2.2.使用{}直接指定值
type[] arrayName = {value1, value2, ..., valueN};
- 在这种方式中,数组的长度由提供的值的数量决定,如果{}为空,则数组长度为0。
1.2.3.new关键字和{}结合
type[] arrayName = new type[size] {value1, value2, ..., valueN};
- 这种方式结合了
new
关键字和花括号,既指定了数组的大小,又提供了初始值。- 如果提供的值的数量少于指定的大小
size
,那么剩余的数组元素将被自动初始化为其类型的默认值。- 如果提供的值的数量多于指定的大小
size
,编译器会报错。
1.3.访问和修改数组元
type element = arrayName[index]; // 访问元素 arrayName[index] = newValue; // 修改元素 int length = arrayName.length;//数组的长度
index
:元素的索引,必须在0到arrayName.length - 1
之间。- 每个数组都有一个
length
属性,它返回数组中的元素数量。案例
/** * 访问数组元素 */ int[] intArray = {10, 20, 30, 40, 50}; // 数组的下标从0开始,所以访问第二个元素(索引为1) int secondElement = intArray[1]; //输出: 20 System.out.println(secondElement); // 数组的下标从0开始,所以访问第四个元素(索引为3) //输出:40 System.out.println(intArray[3]); /** * 修改数组元素 */ intArray[1] = 200; //输出[10, 200, 30, 40, 50] System.out.println(Arrays.toString(intArray)); /** * 获取数组的长度 */ int length = intArray.length; //输出:5 System.out.println(length);
1.4.遍历数组
数组可以通过传统的for
循环、增强型for
循环(For-Each循环)进行遍历。
/**
* 传统 for 循环
*/
int[] numbers = {1, 2, 3, 4, 5};
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
/**
* 增强型 for 循环(For-Each 循环)
*/
for (int number : numbers) {
System.out.println(number);
}
2、二维数组
多维数组可以看作是数组的数组。Java中的多维数组实际上是通过嵌套数组实现的。
2.1.使用new关键字声明二维数组
type[][] arrayName = new type[dimension1][dimension2]; // 对于二维数组
dimension1
和dimension2
分别是数组的两个维度的大小。可以理解为一个大数组中包含着多个小数组,dimension1
是大数组的长度(有几个小数组),dimension2
是小数组的长度(每个小数组中有几个值)。- 这种方式初始化多维数组时,每个元素本身是一个数组,需要进一步初始化。
2.2.使用{}声明二维数组
type[][] arrayName = { {value11, value12}, {value21, value22} };
与一维数组同理理解即可
2.3.二维数组的访问与修改
在 Java 中,二维数组可以被看作是数组的数组,即每个元素本身也是一个数组。以下是如何访问和修改二维数组的元素的示例
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 访问第二行第三列的元素6(注意数组索引从0开始)
int element = matrix[1][2];
System.out.println("访问的元素是: " + element);
// 修改第二行第三列的元素,将元素 6 修改为 10
matrix[1][2] = 10;
// 打印修改后的二维数组
System.out.println(Arrays.toString(matrix));
2.4.二维数组的遍历
以下案例中使用了一个外层循环来遍历二维数组的每一行,然后使用了一个内层循环来遍历每一行中的每个元素。
/**
* 传统for
*/
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 外层循环遍历行
for (int i = 0; i < matrix.length; i++) {
// 内层循环遍历列
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // 每遍历完一行后换行
}
/**
* 增强型 for 循环(For-Each 循环)
*/
// 外层循环遍历行,使用增强型 for 循环
for (int[] row : matrix) {
// 内层循环遍历列,使用传统 for 循环
for (int j = 0; j < row.length; j++) {
System.out.print(row[j] + " ");
}
System.out.println(); // 每遍历完一行后换行
}
3、内存中的数组
- 当程序执行到 int[] arr1的时候,系统会在内存开辟一块空间,变量arr1指向这个空间。
- 之后程序开始解析等于符号右边的内容,也就是创建数组。
- 系统根据指定的数据类型和数组的大小创建一块连续的数组空间,将值存放到空间中。
- 最后将创建的连续的数组空间的地址存入到arr1指向的空间中,这就是赋值。
- 如上图所示,如果将arr1赋值给arr2,其实就是将arr1指向的内存空间中存放的值(数组地址)赋值给arr2,并不是直接将数组赋值给arr2。
以上就是引用类型的内存存储大概逻辑。一个通俗的理解,并不完全严谨。
4、Arrays工具类
4.1.Arrays.asList(T... a)
- 参数:一个可变参数列表
T... a
,表示要转换为列表的元素。 - 返回值:返回一个固定大小的列表(List集合),其元素由参数中的数组元素组成。
- 可变参数:可以传一个或多个值,多个值时(用逗号隔开)编译器会自动分装为一个数组。也可直接传数组(简单解释)。
示例
String[] strArray = {"Java", "Python", "C++"};
//获得一个list集合
List<String> list = Arrays.asList(strArray);
System.out.println(list); // 输出: [Java, Python, C++]
4.2.Arrays.toString(Object[] a)
- 参数:一个对象数组
Object[] a
,表示要转换为字符串的数组。 - 返回值:返回一个字符串,表示数组及其元素的字符串表示。
示例
Integer[] intArray = {1, 2, 3, 4, 5};
//将数组转换成一个易于阅读的字符串表示形式。
//这个方法对于打印数组内容到控制台或记录日志时非常有用
String arrayString = Arrays.toString(intArray);
System.out.println(arrayString); // 输出: [1, 2, 3, 4, 5]
4.3. Arrays.sort(Object[] a)
- 参数:一个对象数组
Object[] a
,表示要排序的数组。 - 返回值:无返回值(
void
),数组在原地被排序。参考《1.4、内存中的数组》
示例:
/**
* Arrays.sort(Object[] a)
* 默认情况下,对数组进行升序排序,即最小的元素排在最前面,最大的元素排在最后面。
*/
String[] strArray = {"banana", "apple", "mango"};
Arrays.sort(strArray);
// 输出: [apple, banana, mango]
System.out.println(Arrays.toString(strArray));
/**
* 要对数组进行降序排序,
* 可以使用 Arrays.sort(Object[] a, Comparator<? super T> c) 方法,
* 并提供一个自定义的比较器(Comparator),该比较器定义了降序排序的规则。
*/
Arrays.sort(strArray, (a, b) -> b.compareTo(a));
// 输出: [mango, banana, apple]
System.out.println(Arrays.toString(strArray));
4.4. Arrays.copyOf(Object[] original, int newLength)
- 参数:一个对象数组
Object[] original
,和一个新长度int newLength
。 - 返回值:返回一个新的数组,其元素是
original
数组的复制,新数组的长度为newLength
。
示例:
Integer[] originalArray = {1, 2, 3};
//可以将数组扩大,也可以缩小,超出的部分截取
Integer[] copiedArray = Arrays.copyOf(originalArray, 5);
// 输出: [1, 2, 3, null, null]
System.out.println(Arrays.toString(copiedArray));
4.5. Arrays.copyOfRange(Object[] original, int from, int to)
- 参数:一个对象数组
Object[] original
,开始索引int from
,结束索引int to
(不包括)。 - 返回值:返回一个新的数组,包含从
from
到to
索引范围内的original
数组元素。
示例:
Integer[] originalArray = {1, 2, 3, 4, 5};
// 复制,从索引1到索引3(不包括索引3),数组的下标是从0开始
Integer[] subArray = Arrays.copyOfRange(originalArray, 1, 3);
System.out.println(Arrays.toString(subArray)); // 输出: [2, 3]