Java 数组

本文最后更新于:2024年3月18日 凌晨

Java 数组

  • Java语言中,数组是一种最简单的复合数据类型,数组的主要特点如下。
    • 数组是相同数据类型元素的集合。
    • 数组中各元素按先后顺序连续存放在内存之中。
    • 每个数组元素用数组名和它在数组中的位置(称为下标)表达。

一维数组

  • 一位数组与数学上的数列有着很大的相似性,数列a1,a2,a3…的特点也是元素名字相同,下标不同,创建一维数组需要以下3个步骤。

声明数组

  • 声明数组要定义数组的名称,维数和数组元素的类型,有以下两种定义格式。
    • 格式1:数组元素类型数组名[ ];
    • 格式2:数组元素类型[ ] 数组名;
  • 数组元素的类型可以是基本类型,也可以是类或接口。例如,要保存某批学生的成绩,可以定义一个数组score,声明如下:
1
Int score[];
  • 该声明定义了一个名为scroe的数组,每个元素类型为整型。

创建数组空间

  • 数组声明只是定义了数组名和类型,并未指定元素个数,与变量一样,数组的每个元素需要占用存储空间,因此必须通过某种方式规定数组的大小,进而确定数组需要的空间。
  • 给已声明的数组分配空间可采用如下格式:
1
score = new int[10];	// 创建含10个元素的整型数组。
  • 也可以在声明数组的同时给数组规定空间,即将数组声明和分配数组空间两步合并。
1
int score = new int[10];
  • 数组元素的下标从0开始,最大下标值为数组的大小减1,当数组的元素类型为基本类型时,在创建存储空间时将按默认规定给各元素赋初值,但如果元素类型为其他引用类型,则其所有元素值为null(代表空引用)
  • 对于以上定义的score数组,10个元素的下标分别为下标分别为score[0],score[1],score[2],…,score[9],每个元素的初值为0

创建数组元素并初始化

  • 另一种给数组分配空间的方法是:声明数组时给数组一个初值表,则数组的元素个数取决于初值表中数据元素个数。格式如下:
1
2
3
int intArr[] = new int[]{1,2,3,4,5,9};
// 或简化如下。
int score[]={1,2,3,4,5,6,7,8,9,10};

注意

  • 数组元素的下标范围是0到 score.length-1,如果下标超出范围,运行时将产生"数组访问越界异常"
  • 编程中常用循环来控制对数组元素的访问,访问数组的下标随循环控制变量变化。

[例4-1]:求10个学生的平均成绩。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Ex4_1 {
public static void main(String[] args) {
int score[] = new int[10];// 求十个学生的平均成绩。
/*以下用随机函数产生10个学生的成绩存入数组score中*/
for (int k = 0; k < score.length; k++) {
score[k] = (int) (Math.random() * 101);
System.out.println(score[k] + "\t");// 输出数组元素。
}
System.out.println();
/*以下计算平均成绩*/
double sum = 0;
for (int k = 0; k < score.length; k++)
sum += score[k];
System.out.println("平均成绩为: " + sum / score.length);
}
}

说明

  • 在该程序中,给数组提供数据和计算平均平均成绩分别用两个循环来处理,虽然可以合并为一个循环,但建议读者还是养成每个程序块功能独立的编程风格,这样程序更清晰。
  • 特别地,对于数组的含一组元素集合,存在一个特殊的for循环语句,类似其他程序设计语言中的for each循环,可遍历访问其中的所有元素,形式如下:
1
for(元素类型循环变量名:数组名){循环体}
  • 因此,将以上求数组所有元素之和的循环语句可改写为:
1
for(int x : score) sum += x;
  • 其中,x的取值将随循环执行过程从score[0],score[1],…,score[9]变化。

[例4-2]:将一维数组元素按由小到大顺序重新排列,排序方法有很多种这里介绍一种最简单的方法,交换排序法,其基本思想如下:

  • 假设对n个元素进行比较,即a[0],a[1],…,a[n-1]
  • 第一遍,目标是在第1个元素处(i=0)放最小值,做法是将第一个元素与后续各元素(i+1~n-1)逐个进行比较,如果有另一个元素比它小,就交换两元素的值。
  • 第二遍,仿照第一遍的做法,在第2个元素处(i=1)放剩下元素中的最小值,,也即将第2个元素与后续元素进行比较。
  • 最后一遍(第n-1遍),将剩下的两个元素a[n-2]与a[n-1]进行比较,在a[n-2]处放最小值,也就是要进行n-1遍比较(外循环),在第i遍(内循环)要进行(n-i)次比较。
  • 程序代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class Ex4_2 {
public static void main(String[] args) {
int a[] = {4,6,3,8,5,3,7,1,9,2};
int n = a.length;
System.out.print("排序前...");
for(int k = 0;k < n;k++)
System.out.print(" "+a[k]);
System.out.println();
/*以下对数组元素按由小到大进行排序*/
for(int i = 0;i <n-1;i++)
for(int j = i+1;j < n;j++)
if(a[i]>a[j]){
/*交换a[i]和a[j]*/
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
System.out.println("排序后...");
for(int k = 0;k < n;k++)
System.out.print(" "+a[k]);
}
}

排序前。
4 6 3 8 5 3 7 1 9 2
排序后。
1 2 3 3 4 5 6 7 8 9

说明

  • 第14~16行交换a[i]和a[j]的值,如果直接用a[i]=a[j],则a[j]=a[i]会导致两个元素的值均为a[j]原来的值,所以引入一个临时变量,而且要注意语句次序。

  • 实际上,Java中有一个Arrays类,其中封装了对数组进行操作的一系列静态方法。

  • 利用Arrays类的sort()方法可方便地对数组排序,例如:

1
java.util.Arrays.sort(a);// 作用等价于上面程序第10\~17行的功能。
  • 利用Arrays类的toString()方法可以将数组转换为串的形式,例如:
1
System.out.println(java.util.Arrays.toString(a));// 将a数组转换为串输出。

多维数组

  • Java中,多维数组被看作数组的数组,多维数组的定义是通过对一维数组的嵌套来实现的,即用数组的数组来定义多维数组。
  • 多维数组中,最常用的是二维数组,下面以二维数组为例介绍多维数组的使用。

声明数组

  • 二维数组的声明与一维数组类似,只是要给出两对方括号,其主要有以下两种格式。
    • 格式一:数组元素类型数组名[ ][ ];
    • 格式二:数组元素类型[ ][ ] 数组名;
1
int a[ ][ ];

创建数组空间

  • 为二位数组创建存储空间有两种方式。

直接为每一维分配空间

1
Int a  = new int 2;
  • 以上定义了两行三列的二维数组a,数组中各元素通过两个下标来区分,每个下标的最小值为0,最大值比行数或列数少1,数组a共包括6个元素,即a[0][0],a[0][1],a[0][2],a[1][0],a[1][1],a[1][2],排列如下所示:

a[0][0] a[0][1] a[0][2]
a[1][0] a[1][1] a[1][2]

  • 从最高维开始,按从高到低的顺序分别为每一维分配空间。
1
2
3
int a[ ][ ] = new int [2][ ];
a[0] = new int[3];
a[1] = new int[4];
  • Java语言中,不要求多维数组每一维的大小相同。
  • 要获取数组的行数,可以通过如下方式获得:
1
数组名.length
  • 要获取数组的列数则要先确定行,在通过如下方式获取该行的列数:
1
数组名[行标].length

[例4-3]:二维数组动态创建示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Ex4_3 {
public static void main(String[] args) {
int[][] m = new int[4][];/// 这nt里只定义了二位数组行的大小。
for (int i = 0; i < m.length; i++) {
m[i] = new int[i + 1];// 对每行创建子数组。
for (int j = 0; j < m[i].length; j++) {
m[i][j] = i + j;
}
}
// 以下按行,列输出数组元素。
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++)
System.out.print(m[i][j] + " ");
System.out.println();
}
}
}

0
1 2
2 3 4
3 4 5 6

说明:第3行定义了二维数组的行数,但没有确定每行的列数,在循环中第5行逐个创建每行的子数组的大小,也就确定列数,但这里它们的大小不一样,引用数组元素时,必须保证访问的数组元素是在已创建号的空间范围内。

创建数组元素并初始化

  • 二维数组初始化与一维数组相同,可用如下方式在数组定义时同时进行初始化。
1
2
int a[ ][ ]= {{1,2,3},{4,5,6}};//2x3的数组。
Int b[ ][ ]= {{1,2},{4,5,6}};//b[0]有两个元素,而b[1]有三个元素。
  • 更为常见的做法是在数组定义后通过二重循环给数组每个元素赋值。