第 3章 数组
第 3章 数 组
3.1 一维数组
3.2 二维数组
第 3章 数组
3.1 一 维 数 组
一维数组是最简单的数组, 在 Java中, 数组是作为
数组类的一个实例来处理的, 故可以用 new运算符来建
立一个数组 。 由于数组中每一个元素都作为一个单独
的对象来考虑, 因而必须逐一建立, 所以定义的时候,
我们必须显式或隐含地指明数组中对象的数目 。 下面
我们分声明和引用两部分来进行介绍 。
第 3章 数组
3.1.1 一维数组的声明和初始化
数组变量在使用之前要事先声明, 其数组元素的
类型可分为三类, 第一类是 Java的基本数据类型;第
二类是 Java类和接口类型 (引用类型 );第三类是数组类
型 。 其一般定义格式如下:
array_type array_Name[ ];
或 array_type [ ]array_Name;
第 3章 数组
上面两种定义方式完全等价 。 对 C/C++熟悉的读者
应该对第一种定义方式并不陌生 。 例如:
int Array1[ ];
Object [ ]Array2;
上面所给的例子只是简单的变量声明, 并没有给
数组分配内存空间 。 我们在使用数组前还必须对其进
行初始化 (即为其分配内存空间 )。 给数组元素分配内存
并为数组元素赋初值的过程称为数组初始化 。 初始化
可分为动态初始化和静态初始化 。
第 3章 数组
1,静态初始化
当数组元素的初始化值直接由括在大括号, { }”之
间的数据给出时, 就称为静态初始化 。 该方法适用于
数组的元素不多且初始元素有限时 。 静态初始化往往
和声明结合在一起使用, 其格式如下:
array_type array_Name={element1[,element2…]};
第 3章 数组
其中, array_type为数组元素的类型; array_Name
为数组名; element1,element2…为 array_type类型的数
组元素初值;方括号, [ ]”表示可选项 。 例如:
int factorial[ ]={ 1,2,3,4,5,6,7,8};
char [ ]ch={'a','A','b','B','c','C'};
double f[ ]={12,45.12,88.123};
第 3章 数组
2,动态初始化
与静态初始化不同, 动态初始化先用 new操作符为
数组分配内存, 然后才为每一个元素赋初值 。 其一般
格式如下:
array_Name = new array_type [ arraySize];
其中, array_Name是已定义的数组名; array_type
为数组元素的数据类型, 必须与定义时给出的数据类
型保持一致; arraySize为数组的长度, 它可为整型变量
或常量 。 例如:
第 3章 数组
...
int series[ ]= new int[4];
for (int i=0;i<4;i++)
series[ i ]=i*3;
...
第 3章 数组
3.1.2 一维数组的引用
当有了数组的声明和初始化后, 与 C/C++相同, 就
可以在程序中引用数组的元素了 。 数组元素的引用是
通过数组名和下标值来进行的, 其一般格式如下:
array_Name [ arrayIndex ]
其中,array_Name为数组名,arrayIndex为数组元
素的下标。数组的下标是一个 int类型数,也可以使用
与 int类型进行自动类型转换的类型,如 short,byte、
char类型 (使用时转换成 int类型 ),但下标不能是 long类
型的数。如果非得用 long类型的数定义数组的下标,
则须强制转换。
第 3章 数组
比如:
...
short i;
byte j;
long k;
int array1 [i],array2[j]; // no error
int array3[k]; // error
int array4[ (int) k]; // it's ok
...
第 3章 数组
在 Java语言中, 数组下标从 0开始, 到数组长度减 1
结束 。 任何数组都有公有变量 length。 我们除了可以在
使用时显式指出数组长度之外, 也可以使用 length这一
数组属性 。 它是只读变量, 只可检测, 不可赋值, 因
为数组一旦分配内存后, 其长度就不再变化 。
为了安全考虑,数组的存取在程序运行时实时检
查,企图使用小于零或大于数组长度的下标都会引起
越界异常 (ArrayIndexOutofBoundException)(异常处理我
们将在后面的章节中给出 )。
第 3章 数组
例如:
...
int array1= new int [10];
array1[-1]= 100; // error,out of bound.
array1 [10]= 200; // error,out of bound.
...
下面我们给出一个完整的例子, 作为本节的总结 。
第 3章 数组
例 3.1
public class TimeSheetDemo {
public static void main (String [ ] args) {
int days = DialogBox.requestInt("number of days
worked");
int [ ] hours;
hours = new int [days];
for (int i=0; i<days; i++) {
hours[i] = DialogBox.requestInt("hours on day
"+(i+1));
}
第 3章 数组
int [ ] salary = new int [days];
for (int i=0; i<days; i++) {
if (hours[i] <= 8) {
salary[i] = 15*hours[i];
} else{
salary[i] = 8*15 + (hours[i]-8)*20;
}
}
Transcript.println("Day\tHours\tSalary");
for (int i=0; i<days; i++) {
第 3章 数组
Transcript.println((i+1)+"\t"+hours[i]+"\t$"+salary[i]);
}
int totalHours = 0;
int totalSalary=0;
for (int i=0; i<days; i++) {
totalHours = totalHours+hours[i];
totalSalary = totalSalary+salary[i];
}
Transcript.println("Total hours,"+totalHours);
Transcript.println("Total salary,$"+totalSalary);
}
}
第 3章 数组
本例的功能是对员工工作的天数、日薪、日工作
时间等进行统计;当每天工作时间不超过 8小时时,每
小时的酬金为 15元,如果超过 8小时,在每小时 15元的
基础上再累加超工作量酬金;最后对工作天数、小时
数、工资进行输出。当我们输入工作天数为 5天,顺序
的工作小时为 9,5,11,8,4后,其输出结果如图 3.1
所示。
第 3章 数组
图 3.1
第 3章 数组
在该例中, 类 DialogBox,Transcript是作者所提供
的标准类, 在附录中我们会给出 。 该程序是在 JBuilder
3.0中运行并通过的 。 作者提供的标准类, 须在 JBuilder
中的 project菜单项中对 properites属性进行设置 。 由于作
者把标准类安装在 E:\packages\genesis目录中, 故须设
置为如图 3.2所示 。 今后例子中所用到的标准类, 如无
特别说明, 均与此例相同 。
第 3章 数组
图 3.2
第 3章 数组
3.2 二 维 数 组
我们在讨论一维数组的时候谈到, 数组的元素类
型可以为数组, 即数组的嵌套, 其实, 多维数组可以
看作是数组的数组 。 也就是说, 多维数组中每个元素
为一个低维数组, 故多维数组的声明, 初始化和引用
与一维数组非常相似 。 由于多维数组中用得较多的还
是二维数组, 因而我们着重讨论二维数组的属性, 其
他高维数组可以以此类推 。
第 3章 数组
3.2.1 二维数组的声明和初始化
与一维数组类似, 二维数组声明的一般格式如下:
array_type array_Name[ ] [ ];
或 array_type [ ] [ ] array_Name;
其中, array_type为数组元素类型, 可以是任意的
数据类型; array_Name为数组名, 可以是 Java中合法的
标识符 。 上面的定义并没有为数组元素分配内存空间,
因而必须经过初始化后才能使用 。
第 3章 数组
例如:
int array1[ ] [ ]; //定义一个整型二维数组
或 int [ ] [ ]array2; //同样定义一个二维整型数组
二维数组在实际的使用过程中也分为静态初始化和
动态初始化两种 。 初始化的过程与一维数组相同, 在此
不多加理论说明, 而只是以初始化实例来加以说明 。
第 3章 数组
1,静态初始化实例
...
int number[ ] [ ]={ {1,2},{3,4},{5,6}};
char ch[ ] [ ]={ {'a','b'},{'c','d'},{'e','f'}};
...
上例是在建立数组的同时用大括号中的值给它赋初值,
得到了两个二维整型数组和二维字符数组 。
第 3章 数组
2,动态初始化实例
...
int array_int =new int[3][3];
//定义数组并为其分配存储空间
long array_long=new long[5][5];
...
第 3章 数组
3.2.2 二维数组的引用
当我们对二维数组进行了初始化后, 就可以在程
序中引用数组的元素了 。 二维数组元素的引用是通过
数组名和下标值来进行的, 其一般格式如下:
array_Name [ arrayIndex1 ] [arrayIndex2]
第 3章 数组
其中, array_Name为数组名; arrayIndex1为数组元
素的高维下标; arrayIndex2为数组的低维下标 。 二维
数组中, 下标同样是一个 int类型数, 也可以使用与 int
类型进行自动类型转换的类型, 如 short,byte,char类
型 (使用时转换成 int类型 ),但下标不能是 long类型的数 。
如果非得用 long类型的数定义数组的下标, 则须强制
转换 。
熟悉 C/C++的读者知道, 在 C/C++使用二维数组的
时候, 要求每一维的长度必须一致, 例如在 C中有如下
的定义,int array [3][];其对应的二维表如表 3.1所示 。
第 3章 数组
表 3.1 C/C++中二维数组存储格式
array[0][0] array[0][1] … array[0][n]
array[1][0] array[1][1] … array[1][n]
array[2][0] array[2][1] … array[2][n]
第 3章 数组
在 Java中, 却并不要求多维数组的每一维长度相同 。
例如, 当在 Java有如下的定义:
int array [3][]=new int[3][];
时, 其对应的二维表如表 3.2所示 。
表 3.2 Java中二维数组存储格式
array[0][0] array[0][1] … array[0][n]
array[1][0] array[1][1] … array[1][m]
array[2][0] array[2][1] … array[2][k]
第 3章 数组
表 3.2中并不要求 n=m=k,实际应用中有可能 n≠m≠k。
下面我们给出一个二维数组应用的实例 。
例 3.2
public class ProcessingMarks {
/*
Processes students' assessment marks.
*/
public static void main (String [] args) {
String
course[]={"Maths","English","Computer","Communicatio
n"};
第 3章 数组
int classSize = 8;
int [][] assessmentMarks = new int [classSize][4];
// for each student
for(int m=0;m<4;m++)
Transcript.print(course[m]+"\t");
Transcript.println();
for (int i=0; i<classSize; i++) {
// for each assessment
第 3章 数组
for (int i=0; i<classSize; i++) {
// for each assessment
for (int j=0; j<4; j++) {
assessmentMarks[i][j]=
(int)(26*Math.random());
Transcript.print(assessmentMarks[i][j]+"\t");
}
Transcript.println();
}
}
}
第 3章 数组
本例是通过二维数组 assesmentMarks对学生的成绩
进行统计,并按四门功课对其输出。程序中定义一维
数组 course来保存对应的每门功课,二维数组
assesmentMarks保存每门功课的成绩。成绩由 Java中
Math包中的随机函数来产生,由于随机数为实数,所
以须强制转换。 Transcript为作者提供的标准类,见附
录。程序的输出结果如图 3.3所示。
第 3章 数组
图 3.3
第 3章 数 组
3.1 一维数组
3.2 二维数组
第 3章 数组
3.1 一 维 数 组
一维数组是最简单的数组, 在 Java中, 数组是作为
数组类的一个实例来处理的, 故可以用 new运算符来建
立一个数组 。 由于数组中每一个元素都作为一个单独
的对象来考虑, 因而必须逐一建立, 所以定义的时候,
我们必须显式或隐含地指明数组中对象的数目 。 下面
我们分声明和引用两部分来进行介绍 。
第 3章 数组
3.1.1 一维数组的声明和初始化
数组变量在使用之前要事先声明, 其数组元素的
类型可分为三类, 第一类是 Java的基本数据类型;第
二类是 Java类和接口类型 (引用类型 );第三类是数组类
型 。 其一般定义格式如下:
array_type array_Name[ ];
或 array_type [ ]array_Name;
第 3章 数组
上面两种定义方式完全等价 。 对 C/C++熟悉的读者
应该对第一种定义方式并不陌生 。 例如:
int Array1[ ];
Object [ ]Array2;
上面所给的例子只是简单的变量声明, 并没有给
数组分配内存空间 。 我们在使用数组前还必须对其进
行初始化 (即为其分配内存空间 )。 给数组元素分配内存
并为数组元素赋初值的过程称为数组初始化 。 初始化
可分为动态初始化和静态初始化 。
第 3章 数组
1,静态初始化
当数组元素的初始化值直接由括在大括号, { }”之
间的数据给出时, 就称为静态初始化 。 该方法适用于
数组的元素不多且初始元素有限时 。 静态初始化往往
和声明结合在一起使用, 其格式如下:
array_type array_Name={element1[,element2…]};
第 3章 数组
其中, array_type为数组元素的类型; array_Name
为数组名; element1,element2…为 array_type类型的数
组元素初值;方括号, [ ]”表示可选项 。 例如:
int factorial[ ]={ 1,2,3,4,5,6,7,8};
char [ ]ch={'a','A','b','B','c','C'};
double f[ ]={12,45.12,88.123};
第 3章 数组
2,动态初始化
与静态初始化不同, 动态初始化先用 new操作符为
数组分配内存, 然后才为每一个元素赋初值 。 其一般
格式如下:
array_Name = new array_type [ arraySize];
其中, array_Name是已定义的数组名; array_type
为数组元素的数据类型, 必须与定义时给出的数据类
型保持一致; arraySize为数组的长度, 它可为整型变量
或常量 。 例如:
第 3章 数组
...
int series[ ]= new int[4];
for (int i=0;i<4;i++)
series[ i ]=i*3;
...
第 3章 数组
3.1.2 一维数组的引用
当有了数组的声明和初始化后, 与 C/C++相同, 就
可以在程序中引用数组的元素了 。 数组元素的引用是
通过数组名和下标值来进行的, 其一般格式如下:
array_Name [ arrayIndex ]
其中,array_Name为数组名,arrayIndex为数组元
素的下标。数组的下标是一个 int类型数,也可以使用
与 int类型进行自动类型转换的类型,如 short,byte、
char类型 (使用时转换成 int类型 ),但下标不能是 long类
型的数。如果非得用 long类型的数定义数组的下标,
则须强制转换。
第 3章 数组
比如:
...
short i;
byte j;
long k;
int array1 [i],array2[j]; // no error
int array3[k]; // error
int array4[ (int) k]; // it's ok
...
第 3章 数组
在 Java语言中, 数组下标从 0开始, 到数组长度减 1
结束 。 任何数组都有公有变量 length。 我们除了可以在
使用时显式指出数组长度之外, 也可以使用 length这一
数组属性 。 它是只读变量, 只可检测, 不可赋值, 因
为数组一旦分配内存后, 其长度就不再变化 。
为了安全考虑,数组的存取在程序运行时实时检
查,企图使用小于零或大于数组长度的下标都会引起
越界异常 (ArrayIndexOutofBoundException)(异常处理我
们将在后面的章节中给出 )。
第 3章 数组
例如:
...
int array1= new int [10];
array1[-1]= 100; // error,out of bound.
array1 [10]= 200; // error,out of bound.
...
下面我们给出一个完整的例子, 作为本节的总结 。
第 3章 数组
例 3.1
public class TimeSheetDemo {
public static void main (String [ ] args) {
int days = DialogBox.requestInt("number of days
worked");
int [ ] hours;
hours = new int [days];
for (int i=0; i<days; i++) {
hours[i] = DialogBox.requestInt("hours on day
"+(i+1));
}
第 3章 数组
int [ ] salary = new int [days];
for (int i=0; i<days; i++) {
if (hours[i] <= 8) {
salary[i] = 15*hours[i];
} else{
salary[i] = 8*15 + (hours[i]-8)*20;
}
}
Transcript.println("Day\tHours\tSalary");
for (int i=0; i<days; i++) {
第 3章 数组
Transcript.println((i+1)+"\t"+hours[i]+"\t$"+salary[i]);
}
int totalHours = 0;
int totalSalary=0;
for (int i=0; i<days; i++) {
totalHours = totalHours+hours[i];
totalSalary = totalSalary+salary[i];
}
Transcript.println("Total hours,"+totalHours);
Transcript.println("Total salary,$"+totalSalary);
}
}
第 3章 数组
本例的功能是对员工工作的天数、日薪、日工作
时间等进行统计;当每天工作时间不超过 8小时时,每
小时的酬金为 15元,如果超过 8小时,在每小时 15元的
基础上再累加超工作量酬金;最后对工作天数、小时
数、工资进行输出。当我们输入工作天数为 5天,顺序
的工作小时为 9,5,11,8,4后,其输出结果如图 3.1
所示。
第 3章 数组
图 3.1
第 3章 数组
在该例中, 类 DialogBox,Transcript是作者所提供
的标准类, 在附录中我们会给出 。 该程序是在 JBuilder
3.0中运行并通过的 。 作者提供的标准类, 须在 JBuilder
中的 project菜单项中对 properites属性进行设置 。 由于作
者把标准类安装在 E:\packages\genesis目录中, 故须设
置为如图 3.2所示 。 今后例子中所用到的标准类, 如无
特别说明, 均与此例相同 。
第 3章 数组
图 3.2
第 3章 数组
3.2 二 维 数 组
我们在讨论一维数组的时候谈到, 数组的元素类
型可以为数组, 即数组的嵌套, 其实, 多维数组可以
看作是数组的数组 。 也就是说, 多维数组中每个元素
为一个低维数组, 故多维数组的声明, 初始化和引用
与一维数组非常相似 。 由于多维数组中用得较多的还
是二维数组, 因而我们着重讨论二维数组的属性, 其
他高维数组可以以此类推 。
第 3章 数组
3.2.1 二维数组的声明和初始化
与一维数组类似, 二维数组声明的一般格式如下:
array_type array_Name[ ] [ ];
或 array_type [ ] [ ] array_Name;
其中, array_type为数组元素类型, 可以是任意的
数据类型; array_Name为数组名, 可以是 Java中合法的
标识符 。 上面的定义并没有为数组元素分配内存空间,
因而必须经过初始化后才能使用 。
第 3章 数组
例如:
int array1[ ] [ ]; //定义一个整型二维数组
或 int [ ] [ ]array2; //同样定义一个二维整型数组
二维数组在实际的使用过程中也分为静态初始化和
动态初始化两种 。 初始化的过程与一维数组相同, 在此
不多加理论说明, 而只是以初始化实例来加以说明 。
第 3章 数组
1,静态初始化实例
...
int number[ ] [ ]={ {1,2},{3,4},{5,6}};
char ch[ ] [ ]={ {'a','b'},{'c','d'},{'e','f'}};
...
上例是在建立数组的同时用大括号中的值给它赋初值,
得到了两个二维整型数组和二维字符数组 。
第 3章 数组
2,动态初始化实例
...
int array_int =new int[3][3];
//定义数组并为其分配存储空间
long array_long=new long[5][5];
...
第 3章 数组
3.2.2 二维数组的引用
当我们对二维数组进行了初始化后, 就可以在程
序中引用数组的元素了 。 二维数组元素的引用是通过
数组名和下标值来进行的, 其一般格式如下:
array_Name [ arrayIndex1 ] [arrayIndex2]
第 3章 数组
其中, array_Name为数组名; arrayIndex1为数组元
素的高维下标; arrayIndex2为数组的低维下标 。 二维
数组中, 下标同样是一个 int类型数, 也可以使用与 int
类型进行自动类型转换的类型, 如 short,byte,char类
型 (使用时转换成 int类型 ),但下标不能是 long类型的数 。
如果非得用 long类型的数定义数组的下标, 则须强制
转换 。
熟悉 C/C++的读者知道, 在 C/C++使用二维数组的
时候, 要求每一维的长度必须一致, 例如在 C中有如下
的定义,int array [3][];其对应的二维表如表 3.1所示 。
第 3章 数组
表 3.1 C/C++中二维数组存储格式
array[0][0] array[0][1] … array[0][n]
array[1][0] array[1][1] … array[1][n]
array[2][0] array[2][1] … array[2][n]
第 3章 数组
在 Java中, 却并不要求多维数组的每一维长度相同 。
例如, 当在 Java有如下的定义:
int array [3][]=new int[3][];
时, 其对应的二维表如表 3.2所示 。
表 3.2 Java中二维数组存储格式
array[0][0] array[0][1] … array[0][n]
array[1][0] array[1][1] … array[1][m]
array[2][0] array[2][1] … array[2][k]
第 3章 数组
表 3.2中并不要求 n=m=k,实际应用中有可能 n≠m≠k。
下面我们给出一个二维数组应用的实例 。
例 3.2
public class ProcessingMarks {
/*
Processes students' assessment marks.
*/
public static void main (String [] args) {
String
course[]={"Maths","English","Computer","Communicatio
n"};
第 3章 数组
int classSize = 8;
int [][] assessmentMarks = new int [classSize][4];
// for each student
for(int m=0;m<4;m++)
Transcript.print(course[m]+"\t");
Transcript.println();
for (int i=0; i<classSize; i++) {
// for each assessment
第 3章 数组
for (int i=0; i<classSize; i++) {
// for each assessment
for (int j=0; j<4; j++) {
assessmentMarks[i][j]=
(int)(26*Math.random());
Transcript.print(assessmentMarks[i][j]+"\t");
}
Transcript.println();
}
}
}
第 3章 数组
本例是通过二维数组 assesmentMarks对学生的成绩
进行统计,并按四门功课对其输出。程序中定义一维
数组 course来保存对应的每门功课,二维数组
assesmentMarks保存每门功课的成绩。成绩由 Java中
Math包中的随机函数来产生,由于随机数为实数,所
以须强制转换。 Transcript为作者提供的标准类,见附
录。程序的输出结果如图 3.3所示。
第 3章 数组
图 3.3