数组
数组是一种数据结构,用于存储一组相同类型的元素。在Java中,数组是一个固定大小的、连续的内存区域,用于存储相同类型的数据。
一维数组
声明数组
声明数组需要指定数组的类型、名称和大小。
int[] numbers = new int[5]; // 声明一个包含5个整数的数组
//也可写作
int numbers2[] = new int[5];
初始化数组
-
在声明数组时初始化:
数据类型[] 数组名变量 = new 数据类型[]{元素1,元素2,...}
数据类型[] 数组名变量 = {元素1,元素2,...}
int[] intArr3 = new int[]{1,2,3}; double[] intArr4 = {1.3,2,3.14};
-
在声明数组后初始化。可以使用循环或逐个赋值的方式进行初始化。
numbers[0] = 10; // 为第一个元素赋值 numbers[1] = 20; // 为第二个元素赋值
访问数组元素
可以使用索引来访问数组中的特定元素。索引从0开始,依次递增,不会超过数组长度减1。
格式:数组变量名[下标]
补充:数组在创建时的默认值:
数组类型 | 默认值 |
---|---|
int[] | 0 |
double[] | 0.0 |
char[] | ‘’ |
boolean[] | false |
引用数据类型 | null |
数组长度
使用 length
属性可以获取数组的长度,即数组中元素的个数。
int size = numbers.length; // 获取数组的长度
遍历数组
将数组中的数据逐个取出
遍历的方式:
- for循环下标遍历:需要使用下标对数组元素进行操作时,使用该方式
- 增强for循环遍历:只获取数组元素的值,不进行改变
补充:
IDEA的代码补全:
数组名.for
增强for循环遍历
数组名.fori
for循环下标遍历
数组名.forr
for循环倒序遍历
操作数组的API
操作数组时,Java提供了一些常用的API来帮助我们进行数组的处理。下面是一些常用的数组操作API:
-
java.util.Arrays
类:提供了一系列静态方法来操作数组,如排序、填充、复制等。-
sort(arr)
:对数组进行升序排序。 -
sort(arr, comparator)
:使用自定义比较器对数组进行排序。 -
fill(arr, value)
:将数组的所有元素都设置为指定的值。 -
copyOf(arr, length)
:复制数组的指定长度部分。 -
equals(arr1, arr2)
:比较两个数组是否相等。 -
toString(arr)
:将数组转换为字符串形式。
-
-
System.arraycopy
是 Java 中用于数组复制的方法。它可以将一个数组中的元素复制到另一个数组中,并且可以选择性地指定起始位置和复制的长度。
方法签名如下:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
参数说明:
src
:源数组,即要复制的数组。srcPos
:源数组中的起始位置,从该位置开始复制元素。dest
:目标数组,即要将元素复制到的数组。destPos
:目标数组中的起始位置,从该位置开始将元素复制到目标数组。length
:要复制的元素个数。
示例:
int[] sourceArray = {1, 2, 3, 4, 5};
int[] destinationArray = new int[5];
System.arraycopy(sourceArray, 0, destinationArray, 0, 5);
上述代码将 sourceArray
中的所有元素复制到 destinationArray
中。sourceArray
的起始位置是 0,destinationArray
的起始位置也是 0,要复制的元素个数为 5。执行完毕后,destinationArray
中的元素将变为 {1, 2, 3, 4, 5}
。
注意事项:
src
和dest
参数必须引用同一类型的数组,或者是该类型的超类。- 如果源数组的长度小于
srcPos + length
,或者目标数组的长度小于destPos + length
,将抛出ArrayIndexOutOfBoundsException
异常。 - 如果
src
或dest
为null
,将抛出NullPointerException
异常。
二维数组
二维数组是一种多维数组,它可以存储表格或矩阵等具有行和列的数据结构。在Java中,二维数组是数组的数组,每个元素本身也是一个数组,它们具有相同的类型。
声明和初始化二维数组的方式如下:
dataType[][] arrayName = new dataType[rowSize][colSize];
其中:
dataType
是数组中元素的数据类型。arrayName
是数组的名称。rowSize
是二维数组的行数。colSize
是二维数组的列数。
例如,创建一个 3x3 的整数二维数组:
int[][] matrix = new int[3][3];
可以通过下标访问和修改二维数组中的元素。行索引和列索引都从 0 开始。
matrix[0][0] = 1; // 设置第一行第一列的元素为 1
int element = matrix[1][2]; // 获取第二行第三列的元素
遍历二维数组通常使用嵌套的循环结构,外层循环用于遍历行,内层循环用于遍历列。
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
int element = matrix[i][j];
// 对当前元素进行操作
}
}
堆栈
- 堆(Heap):堆是用于动态分配内存的一个区域。在堆中分配的内存可以在程序的任何地方进行访问,它的生命周期由程序员管理。在Java中,对象的实例通常存储在堆中。
- 栈(Stack):栈是一种线性数据结构,具有后进先出(LIFO)的特性。栈用于存储局部变量、方法调用信息和临时数据等。栈的大小是固定的,并且由编译器进行管理。
数组与堆栈
在内存中,实例化的数组以连续的内存块形式存储。具体存储方式如下:
- 数组对象:在堆内存中,会分配一块内存用于存储数组对象本身的信息,包括数组的长度和其他元数据。该内存块的地址被用作数组对象的引用。
- 元素存储:紧接着数组对象之后,会按照数组的长度分配连续的内存空间来存储数组的元素。元素的存储顺序与数组的索引对应,即较小索引的元素存储在较低的内存地址,较大索引的元素存储在较高的内存地址。
通过数组对象的引用,我们可以访问和操作数组中的元素。例如,使用 array[2]
可以访问索引为2的元素,并对其进行读取或写入操作。
在Java中,数组的引用(即指向数组对象的地址)会存储在栈内存中。栈内存用于存储方法调用的信息、局部变量和操作数栈等。
当一个数组被声明为局部变量时,它的引用会被存储在栈内存中。所以在方法中创建的数组对象的引用将在方法执行结束后被销毁。但数组对象本身仍然存在于堆内存中。
public void exampleMethod() {
int[] array = new int[5];
}
在上述代码中,array
是一个局部变量,它的引用将被存储在栈内存中。当 exampleMethod()
方法被调用时,栈内存中会为该方法分配一块内存空间,并在其中存储局部变量和其他方法调用信息。其中,array
的引用将被存储在该内存空间中。
数组的元素本身并不存储在栈内存中。数组的元素仍然存储在堆内存中,而栈内存中存储的仅仅是对数组对象的引用。
总结起来,数组的引用会存储在栈内存中,而数组的元素则存储在堆内存中。栈内存中存储的是对数组对象的引用,而不是实际的数组元素。
方法被调用时,栈内存中会为该方法分配一块内存空间,并在其中存储局部变量和其他方法调用信息。其中,array
的引用将被存储在该内存空间中。
数组的元素本身并不存储在栈内存中。数组的元素仍然存储在堆内存中,而栈内存中存储的仅仅是对数组对象的引用。
总结起来,数组的引用会存储在栈内存中,而数组的元素则存储在堆内存中。栈内存中存储的是对数组对象的引用,而不是实际的数组元素。