在解决实际问题的过程中,往往需要处理大量相同类型的数据,而且这些数据被反复使用。这种情况下,可以考虑使用数组来存储数据。数组就是相同类型的数据按顺序组成的一种复合型数据类型。数据类型可以是基本数据类型,也可以是引用数据类型。当数组元素的类型仍然是数组时,就构成了多维数组。
数组名可以是任意合法的Java标识符。通过数组名和下标来使用数组中的数据,下标从0开始。使用数组的最大好处是可以让一批相同性质的数据共用一个变量名,而不必为每个数据命名一个名字。使用数组不仅使程序书写大为简便清晰,可读性大大提高,而且便于用循环语句处理这类数据。
一维数组是指维度为1的数组。它是数组最简单的形式,也是最常用的数组。
与变量一样,使用数组之前,必须先声明数组。声明一维数组的语法格式有以下两种形式。
数据类型 数组名[ ];
数据类型 [ ] 数组名;
其中,数据类型可以是基本数据类型,也可以是引用数据类型。数组名可以是任意合法的Java标识符,例如如下代码。
int [] a1; //声明整型数组a1
double b1[]; //声明浮点型数组b1
在声明数组时,不能指定数组的长度,否则编译无法通过。
声明数组仅为数组指定数组名和数组元素的类型,并没有为元素分配实际的存储空间。需要为数组分配空间才能使用。
分配空间就是告诉计算机在内存中为它分配几个连续的位置存储数据。在Java中使用new关键字为数组分配空间。其语法格式如下。
数组名 = new 数据类型[数组长度];
其中,数组长度就是数组中能存放的元素个数,是大于0的整数,例如如下代码。
a1 = new int[10]; //为数组a1分配能存放10个整数的空间
b1 = new double[20]; //为数组b1分配能存放20个double型数据的空间
也可以在声明数组时就为它分配空间,语法格式如下。
数据类型 数组名[ ] = new 数据类型[数组长度];
例如:
int a2[] = new int[10]; //声明数组的同时并分配空间
数组的大小一旦确定,就不能再修改。
初始化一维数组是指分别为数组中的每个元素赋值。可以通过以下两种方法进行数组的初始化。
(1)直接指定初值的方式
在声明一个数组的同时将数组元素的初值依次写入赋值号后的一对花括号内,给这个数组的所有元素赋初始值。这样,Java编译器可通过初值的个数确定数组元素的个数,为它分配足够的存储空间并将这些值写入相应的存储单元。
语法格式如下。
数据类型 数组名[ ] = {元素值1, 元素值2, 元素值3, ... , 元素值n};
例如:
int [ ] a1 = {23,-9,38,8,65};
double b1[] = {1.23, -90.1, 3.82, 8.0 ,65.2};
(2)通过下标赋值的方式
数组元素在数组中按照一定的顺序排列编号,首元素的编号规定为0,其他元素顺序编号。元素编号也称为下标或索引。因此,数组下标依次为0,1,2,3,…。数组中的每个元素可以通过下标进行访问,例如a1[0]表示数组的第一个元素。
通过下标赋值的语法格式如下。
数组名[下标] = 元素值;
例如:
a1[0] = 13;
a1[1] = 14;
a1[2] = 15;
a1[3] = 16;
...
下面通过一个实例,让读者对数组的应用有进一步的了解。
【例2-26】一维数组应用举例。
功能实现: 在数组中存放4位同学的成绩,计算这4位同学的总成绩和平均成绩。
public class Array1Test {
public static void main(String[] args){
double score[]={76.5,88.0,92.5,65};
double sum =0;
for(int i=0;i<score.length;i++){
sum = sum + score[i];
}
System.out.println("总 成 绩 为:" + sum);
System.out.println("平均成绩为:" + sum/score.length);
}
}
程序执行结果如图2-25所示。
图2-25 例2-26的执行结果
注意事项 在Java语言中,数组是一种引用类型,拥有方法和属性。例如在例子中出现的length就是它的一个属性,利用该属性可以获得数组的长度。
JDK 1.5引进了一种新的循环类型,被称为For-Each循环或者增强型循环。它能在不使用下标的情况下遍历数组。语法格式如下:
for(type element: array){
System.out.println(element);
}
其中type是数组元素类型,element是一个局部变量,array是要遍历的数组。下面通过例子具体演示增强for循环的用法。
【例2-27】使用增强for循环遍历数组中的元素。
程序运行结果如图2-26所示。
图2-26 例2-27的执行结果
在介绍数组基本概念时,已经给出这样的结论:数组元素可以是Java语言允许的任何数据类型。当数组元素的类型是数组时,就构成多维数组。例如,二维数组实际上就是每个数组元素是一个一维数组的一维数组。
这里以二维数组为例。声明多维数组的语法格式有以下两种方式:
数据类型 数组名[ ] [ ];
数据类型 [ ] [ ] 数组名;
例如:
int [][]matrix; //整型二维数组
double b1[][][]; //浮点型三维数组
在声明数组时,不能指定数组的长度,否则编译无法通过。
声明数组仅为数组指定数组名和数组元素的类型,并没有为元素分配实际的存储空间。需要为数组分配空间才能使用。
分配空间就是告诉计算机在内存中为它分配几个连续的位置存储数据。在Java中使用new关键字为数组分配空间。为多维数组(这里以三维数组为例)分配空间的语法格式如下:
数组名 = new 数据类型[数组长度1] [数组长度2] [数组长度3];
其中,数组长度1是第一维数组元素个数,数组长度2是第二维数组元素个数,数组长度3是第三维数组元素个数。
例如:
matrix = new int[3] [3]; //为整型二维数组分配空间
b1[][][]= new double[3] [5] [5]; //为浮点型三维数组分配空间
也可以在声明数组时,就为它分配空间,语法格式如下:
数据类型 数组名[ ] [ ] [ ] = new 数据类型[数组长度1] [数组长度2] [数组长度3];
例如:
int array3[][][] = new int[2] [2] [3];
该数组有2*2*3个元素,各元素在内存中的存储情况如表2-9所示。
表2-9 三维数组array3的元素存储情况
初始化多维数组是指分别为多维数组中的每个元素赋值。可以通过以下两种方法进行数组的初始化。
(1)直接指定初值的方式
在声明一个多维数组的同时将数组元素的初值依次写入赋值号后的一对花括号内,给这个数组的所有元素赋初始值。这样,Java编译器可通过初值的个数确定数组元素的个数,为它分配足够的存储空间并将这些值写入相应的存储单元。
这里以二维数组为例,其语法格式如下:
数据类型 数组名[ ] [ ] = {数组1, 数组2 };
例如:
int matrix2[][] = {{1, 2, 3}, {4,5,6}};
(2)通过下标赋值的方式
例如:
int matrix3[][] = new int[2][3];
matrix3 [0] [0] = 0;
matrix3 [0] [1] = 1;
matrix3 [0] [2] = 2;
matrix3 [1] [0] = 3;
matrix3 [1] [1] = 4;
matrix3 [1] [2] = 5;
以二维数组为例,可用length()方法测定二维数组的长度,即元素的个数。只不过使用“数组名.length”得到的是二维数组的行数,而使用“数组名[i].length”得到的是该行的列数。
下面通过一个实例对上述内容进行进一步的解释,首先声明一个二维数组
int[ ][ ] arr1={{3, -9},{8,0},{11,9} };
则arr1.length的返回值是3,表示数组arr1有3行。而arr1[1].length的返回值是2,表示arr1[1]对应的行(第二行)有2个元素。
【例2-28】声明并初始化一个二维数组,然后输出该数组中各元素的值。
程序执行结果如图2-27所示。
图2-27 例2-28的执行结果