数组是连续内存单元中一组名字和数据类型相同的数据元素的有限集合。数组可以用来保存和处理一组数据类型相同的数据元素。数组中的每个数据元素称作一个数组元素。
当把一维数组中的每个数据元素定义为一个一维数组时,就构成了Java语言的二维数组,以此类推,还可以有三维数组甚至更多维数组。另外,Java语言可以构造出不规则数组。
1、一维数组
和变量的使用方法类同,一维数组也要先定义后使用,不同的是数组在定义后还要经过内存单元分配后才能使用。
Java语言一维数组的使用分三步:定义一维数组变量、为数组分配内存单元和使用数组元素。
1.一维数组变量定义
一维数组变量定义的语法形式为:
<</SPAN>数据类型><</SPAN>数组名>[];
或
<</SPAN>数据类型>[]<</SPAN>数组名>;
其中,方括号[]表示定义的是数组变量,<</SPAN>数据类型>定义了数组元素的数据类型,<</SPAN>数组名>定义了数组名的标识符。
也可以把数组类型看成是Java语言在基本数据类型的基础上的扩展。
例如:
int[] a;
定义了一个数据类型为int、数组标识符为a的一维数组。
在数组定义后,系统将给数组标识符分配一个内存单元,用于指示数组在内存中的实际存放位置。由于在数组变量定义时,数组元素本身在内存中的实际存放位置还没有给出,所以,此时该数组名的值为空(null)。例如,上述语句执行后数组a的状态如图下图中的(a)所示:
java1-1.gif
2.为数组分配内存单元
Java语言中,new是一个特殊的运算符。new运算符的语法形式为:
new <</SPAN>数据类型>
new运算符的语义是:向系统申请指定数据类型所需的内存单元空间。new运算符返回所申请内存单元的首地址。
数组元素本身的内存空间必须用new运算符在程序中申请。只有用new运算符为数组分配了内存单元空间后,存放一个数组的所有数组元素所需的内存空间才真正被系统分配了。为数组类型变量分配内存单元的语法形式为:
<</SPAN>数组名> = new <</SPAN>数据类型>[<</SPAN>长度>];
其中,<</SPAN>数组名>必须是已定义的数组类型变量,<</SPAN>数据类型>必须和定义数组名时的数据类型一致,方括号[]内的<</SPAN>长度>指出了当前数组元素的个数。
例如:
a = new int[5];
就具体分配了包含5个int类型数组元素的内存单元,并把该块内存单元的首地址赋值给数组名a
Java语言规定,在数组分配内存单元后,系统将自动给每个数组元素赋初值,并规定:数值类型的数组元素初值为0,逻辑类型的数组元素初值为false,类类型的数组元素初值为null。执行该语句后的示意图如上图中的(b)
3.使用数组元素
一旦完成了定义数组变量和为数组分配内存单元后,就可以使用数组中的任意数组元素。数组元素由数组名、一对方括号、方括号中的整数数值(一般称作下标)组成。其中下标指出了希望操作的数组元素位置。下标由0开始,其最大值为用new运算符分配内存单元时规定的长度值减1。各数组元素在内存中按下标的升序连续存放。上述数组a的5个元素依次是a[0],a[1],a[2],a[3],a[4]。
例如:
a[0] = 10;
语句就给数组元素a[0]赋了数值10。执行该语句后的示意图如上图中的(c)
4.引用类型
前面讨论的用基本数据类型定义变量和这里讨论的定义数组变量有一些不同。用基本数据类型定义的变量,其变量名表示这个变量名中存放的数值,如有下列语句段:
int i, x; //定义变量
i = 10; //给变量i赋值
x = 10 + i; //使用变量i中的数值
上述语句段中,变量i的存储结构如下图中的(a)所示,语句 x = 10 + i中,赋值号右边的变量i表示变量i中的数值10。
java1-2.gif
对于数组变量,设有下列语句段:
int[] a;
int x;
a = new int[5];
a[0] = 10; //给数组元素a[0]赋值
x = 10 + a[0]; //使用数组元素a[0]中的数值
x = 10 + a; //错误,数值10和数组名 a为不兼容的类型
上述语句段中,数组a的存储结构如上图中的(b)所示,语句 x = 10 + a[0]中,赋值号右边的数组元素a[0]表示数组元素a[0]中的数值,但语句x = 10 + a将出错,因为数组名 a是指向内存中存放数组元素的一片连续内存单元的首地址,所以,数值10和数组名 a为不兼容的类型。
Java语言中,数组名的类型是引用类型。所谓引用类型,是指该类型的标识符表示的是一片内存连续地址的首地址。
引用类型是非常重要的一个概念。下一节要讨论字符串,字符串名和数组名一样,也是引用类型。
5.数组的简化使用方法
数组的定义和为数组分配内存空间两步可以结合起来。
例如:
int a[] = new int[ 5];
就在定义int类型数组变量a的同时为数组分配了5个int类型数组元素所需的内存空间,并给每个数组元素初始赋值0。
数组元素的初始化赋值也可以和上述语句结合在一起完成,此时采用简写形式。例如,
int a[] = {1,2,3,4,5};
就在定义int类型数组变量a、为数组分配了5个int类型数组元素所需的内存空间的同时,初始化给数组元素a[0]赋初值1,a[1]赋初值2,……,a[4]赋初值5
6.数组元素允许的运算
对数组元素可以进行其数据类型所允许的任意运算。
例如:
int u = 3, v = 4, x, y;
int a[] = {1,2,3,4,5};
x = (a[2] + a[3] – u) * v;
y = a[1] / u;
都是合法的表达式。
7.数组的长度
Java语言提供了length成员变量返回数组元素的个数,其使用方法为:
<</SPAN>数组名>.length
例如:
int n;
int a[] = new int[ 10];
n = a.length;
则有n等于10。
8.数组长度的重新定义
一旦为数组规定了长度,在程序中使用数组时就不能超过所规定的长度,否则编译时会给出“数组下标越界”的语法错误。例如,若数组分配的内存空间为5个,则语句中一旦出现a[5]将产生“数组下标越界”的语法错误。
上述情况下,可以用new运算符重新为数组分配内存单元。例如,
a = new int[ 10];
上述语句后,由于重新为数组a分配了10个int类型的内存单元空间,所以,此时若语句中出现a[5],编译时将不会出现“数组下标越界”的语法错误。
【例2.11】求10个数中的最小数。
要求:用数组初始化赋值方法给出10个整数数值。
程序设计如下:
public class Exam2_11
{
public static void main(String args[])
{
int i, min;
int a[] = {30,81,37,45,26,46,44,78,80,64}; //初始化赋值
System.out.print("数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(" " + a[i]); //输出数组元素
//寻找数组中数值最小的元素
min = a[0];
for(i = 1; i < a.length; i++)
if(a[i] < min) min = a[i];
System.out.println("\n最小数为:" + min);
}
}
程序的运行结果为:
数组元素为: 30 81 37 45 26 46 44 78 80 64
最小数为:26
如果此问题不用数组方法设计,而用简单变量方法设计,程序将非常复杂。因此,数组是复杂问题的程序设计所必需的。
------------------------------------------------------------------------------------------------------
【例2.12】把10个数按从小到大的次序排序。
要求:用数组初始化赋值方法给出10个整数数值,用直接交换排序算法排序。
直接交换排序算法思想:例2.11程序找到的是数组a中的最小数。如果我们在此基础上设计一个循环过程,把每次找到的最小数和数组中尚未排好序的数据元素交换,下次循环时,从这个数据元素的下一个位置开始,继续这样的寻找和交换过程。这样的过程共进行a.length-1次,则全部数组中的数据元素就按从小到大的次序排好了。
程序设计如下:
public class Exam2_12
{
public static void main(String args[])
{
int a[] = {30,81,37,45,26,46,44,78,80,64};
int i, j, min, temp;
System.out.println("排序前数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
//直接交换排序
for(i = 0; i < a.length-1; i++) //循环a.length-1次
{
min = i;
for(j = i+1; j < a.length; j++)
if(a[j] < a[min]) min = j; //寻找最小数
if(min != i) //判断是否需要交换
{
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
System.out.println("\n排序后数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
}
}
程序的运行结果为:
排序前数组元素为:
30 81 37 45 26 46 44 78 80 64
排序后数组元素为:
26 30 37 44 45 46 64 78 80 81
2、二维数组
Java语言只定义了一维数组,但是,如果一维数组的每个数组元素都是一个一维数组,则构成了Java语言的二维数组。和一维数组的使用方法类同,二维数组的使用也分三步:定义数组变量、为数组分配内存单元和使用数组元素。
1.二维数组定义:
二维数组变量定义的一个例子如下:
int a[][];
或
int[] a[];
上面语句定义了一个数据类型为int[](即一维数组类型)、标识符为a的一维数组,即数组a是二维数组。
上述语句执行后数组a的内存状态如下图中的(a)所示:
java1-3.gif
为二维数组变量分配内存单元时必须指定每一维的数组元素个数。
例如:
a = new int[3][3];
就具体分配了包含3个int[3]类型数组元素的内存单元,并把该连续内存单元的首地址赋给数组名a,同时为每个数组元素初始化赋值0。
上图中的(b)就是上述语句执行后的内存示意图。
使用二维数组元素的方法和使用一维数组元素的方法类同,只是这里要指出二维数组的每一维的下标。例如,语句
a[0][0] = 10;
就给数组元素a[0][0]赋了数值10。如上图(c)所示。
2.二维数组简化:
同样,二维数组也可以用简化方法。例如:
int a[][] = new int[5][5];
就在定义int类型的二维数组变量a的同时,为数组分配了内存单元结构如图2.2(b)所示的5个每一维为int[5]类型数组元素的内存空间,并给每个数组元素初始赋值0。
又例如:
int a[][] = {{1,2,3},{4,5,6},{7,8,9}};
就在定义int类型二维数组变量a、并为二维数组动态分配了9个int类型数组元素内存空间的同时,初始化给数组元素a[0][0]赋初值1,a[0][1]赋初值2,a[0][2]赋初值3,a[1][0]赋初值4,……,a[2][2]赋初值9。
三维数组或更多维数组的使用方法和二维数组的使用方法类同。
【例2.13】求C = A×BT,其中,A是一个行向量,BT是一个列向量,C是一个矩阵。例如,设A和B均为n=3的向量,则矩阵C元素的计算方法是:c11=a1*b1,c12=a1*b2,c13=a1*b3,c21=a2*b1,……,c33=a3*b3。
设计思想:这是一个矩阵运算。用一维数组 a存放行向量A,用一维数组 b存放列向量BT,用两维数组存放矩阵C。
程序设计如下:
public class Exam2_13
{
public static void main(String args[])
{
final int n = 3;
int a[] = {1,2,3};
int b[] = {4,5,6};
int c[][] = new int[n][n];
int i, j;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
c[i][j] = a[i] * b[j]; //计算cij
System.out.println (”二维数组元素为:”);
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
System.out.print(c[i][j] + " ");
System.out.println();
}
}
}
程序运行输出结果为:
二维数组元素为:
4 5 6
8 10 12
12 15 18
3、不规则的二维数组
由于Java语言的二维数组是由一维数组定义的,所以,可以把二维数组中的每个一维数组定义为不同的元素个数,这样就可以构成不规则的二维数组。
不规则二维数组的具体设计方法是:先定义一个二维数组变量,并指定第一维的元素个数,然后再分别为第二维数组(即第一维数组的每个数组元素)分配不同的内存单元。由于此时是分别为第二维数组分配内存单元,并且第二维数组所分配的内存单元个数可以是不相同的,因此就构成了不规则的二维数组。
例如,下面的代码先定义一个二维数组,并为数组的第一维数组元素分配空间(这就要求必须指定其具体个数),然后再分别为第二维数组元素分配不同的内存空间。
int twoDim [][] = new int [4][]; //定义二维数组,并指定第一维的元素个数
twoDim[0] = new int[1]; //指定第二维第一个元素的个数
twoDim[1] = new int[2]; //指定第二维第二个元素的个数
twoDim[2] = new int[3]; //指定第二维第三个元素的个数
twoDim[3] = new int[4]; //指定第二维第四个元素的个数
数组twoDim得到的内存单元结构如下图所示:
java1-4.gif
【例2.14】计算并保存九九乘法表,要求重复的部分只保存一个。
设计思想:九九乘法表需要一个二维数组来保存,因为要求重复的部分(如1*2和2*1)只保存一个,所以需要把二维数组定义成不规则的二维数组。
程序设计如下:
public class Exam2_14
{
public static void main(String args[])
{
final int N = 9;
int a[][] = new int [N][]; //定义二维数组,并指定第一维的元素个数
int i,j;
for(i = 0; i < N; i++)
a[i] = new int [i+1]; //指定不规则的第二维的个数
for(i = 0; i < N; i++)
for(j = 0; j <= i; j++)
a[i][j] = (i + 1) * (j + 1); //保存乘法表
//输出乘法表
for(i = 0; i < N; i++)
{
for(j = 0; j <= i; j++)
System.out.print(a[i][j] + " ");
System.out.println();
}
}
}
程序运行输出如下:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
8 16 24 32 40 48 56 64
9 18 27 36 45 54 63 72 81
当把一维数组中的每个数据元素定义为一个一维数组时,就构成了Java语言的二维数组,以此类推,还可以有三维数组甚至更多维数组。另外,Java语言可以构造出不规则数组。
1、一维数组
和变量的使用方法类同,一维数组也要先定义后使用,不同的是数组在定义后还要经过内存单元分配后才能使用。
Java语言一维数组的使用分三步:定义一维数组变量、为数组分配内存单元和使用数组元素。
1.一维数组变量定义
一维数组变量定义的语法形式为:
<</SPAN>数据类型><</SPAN>数组名>[];
或
<</SPAN>数据类型>[]<</SPAN>数组名>;
其中,方括号[]表示定义的是数组变量,<</SPAN>数据类型>定义了数组元素的数据类型,<</SPAN>数组名>定义了数组名的标识符。
也可以把数组类型看成是Java语言在基本数据类型的基础上的扩展。
例如:
int[] a;
定义了一个数据类型为int、数组标识符为a的一维数组。
在数组定义后,系统将给数组标识符分配一个内存单元,用于指示数组在内存中的实际存放位置。由于在数组变量定义时,数组元素本身在内存中的实际存放位置还没有给出,所以,此时该数组名的值为空(null)。例如,上述语句执行后数组a的状态如图下图中的(a)所示:
java1-1.gif
2.为数组分配内存单元
Java语言中,new是一个特殊的运算符。new运算符的语法形式为:
new <</SPAN>数据类型>
new运算符的语义是:向系统申请指定数据类型所需的内存单元空间。new运算符返回所申请内存单元的首地址。
数组元素本身的内存空间必须用new运算符在程序中申请。只有用new运算符为数组分配了内存单元空间后,存放一个数组的所有数组元素所需的内存空间才真正被系统分配了。为数组类型变量分配内存单元的语法形式为:
<</SPAN>数组名> = new <</SPAN>数据类型>[<</SPAN>长度>];
其中,<</SPAN>数组名>必须是已定义的数组类型变量,<</SPAN>数据类型>必须和定义数组名时的数据类型一致,方括号[]内的<</SPAN>长度>指出了当前数组元素的个数。
例如:
a = new int[5];
就具体分配了包含5个int类型数组元素的内存单元,并把该块内存单元的首地址赋值给数组名a
Java语言规定,在数组分配内存单元后,系统将自动给每个数组元素赋初值,并规定:数值类型的数组元素初值为0,逻辑类型的数组元素初值为false,类类型的数组元素初值为null。执行该语句后的示意图如上图中的(b)
3.使用数组元素
一旦完成了定义数组变量和为数组分配内存单元后,就可以使用数组中的任意数组元素。数组元素由数组名、一对方括号、方括号中的整数数值(一般称作下标)组成。其中下标指出了希望操作的数组元素位置。下标由0开始,其最大值为用new运算符分配内存单元时规定的长度值减1。各数组元素在内存中按下标的升序连续存放。上述数组a的5个元素依次是a[0],a[1],a[2],a[3],a[4]。
例如:
a[0] = 10;
语句就给数组元素a[0]赋了数值10。执行该语句后的示意图如上图中的(c)
4.引用类型
前面讨论的用基本数据类型定义变量和这里讨论的定义数组变量有一些不同。用基本数据类型定义的变量,其变量名表示这个变量名中存放的数值,如有下列语句段:
int i, x; //定义变量
i = 10; //给变量i赋值
x = 10 + i; //使用变量i中的数值
上述语句段中,变量i的存储结构如下图中的(a)所示,语句 x = 10 + i中,赋值号右边的变量i表示变量i中的数值10。
java1-2.gif
对于数组变量,设有下列语句段:
int[] a;
int x;
a = new int[5];
a[0] = 10; //给数组元素a[0]赋值
x = 10 + a[0]; //使用数组元素a[0]中的数值
x = 10 + a; //错误,数值10和数组名 a为不兼容的类型
上述语句段中,数组a的存储结构如上图中的(b)所示,语句 x = 10 + a[0]中,赋值号右边的数组元素a[0]表示数组元素a[0]中的数值,但语句x = 10 + a将出错,因为数组名 a是指向内存中存放数组元素的一片连续内存单元的首地址,所以,数值10和数组名 a为不兼容的类型。
Java语言中,数组名的类型是引用类型。所谓引用类型,是指该类型的标识符表示的是一片内存连续地址的首地址。
引用类型是非常重要的一个概念。下一节要讨论字符串,字符串名和数组名一样,也是引用类型。
5.数组的简化使用方法
数组的定义和为数组分配内存空间两步可以结合起来。
例如:
int a[] = new int[ 5];
就在定义int类型数组变量a的同时为数组分配了5个int类型数组元素所需的内存空间,并给每个数组元素初始赋值0。
数组元素的初始化赋值也可以和上述语句结合在一起完成,此时采用简写形式。例如,
int a[] = {1,2,3,4,5};
就在定义int类型数组变量a、为数组分配了5个int类型数组元素所需的内存空间的同时,初始化给数组元素a[0]赋初值1,a[1]赋初值2,……,a[4]赋初值5
6.数组元素允许的运算
对数组元素可以进行其数据类型所允许的任意运算。
例如:
int u = 3, v = 4, x, y;
int a[] = {1,2,3,4,5};
x = (a[2] + a[3] – u) * v;
y = a[1] / u;
都是合法的表达式。
7.数组的长度
Java语言提供了length成员变量返回数组元素的个数,其使用方法为:
<</SPAN>数组名>.length
例如:
int n;
int a[] = new int[ 10];
n = a.length;
则有n等于10。
8.数组长度的重新定义
一旦为数组规定了长度,在程序中使用数组时就不能超过所规定的长度,否则编译时会给出“数组下标越界”的语法错误。例如,若数组分配的内存空间为5个,则语句中一旦出现a[5]将产生“数组下标越界”的语法错误。
上述情况下,可以用new运算符重新为数组分配内存单元。例如,
a = new int[ 10];
上述语句后,由于重新为数组a分配了10个int类型的内存单元空间,所以,此时若语句中出现a[5],编译时将不会出现“数组下标越界”的语法错误。
【例2.11】求10个数中的最小数。
要求:用数组初始化赋值方法给出10个整数数值。
程序设计如下:
public class Exam2_11
{
public static void main(String args[])
{
int i, min;
int a[] = {30,81,37,45,26,46,44,78,80,64}; //初始化赋值
System.out.print("数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(" " + a[i]); //输出数组元素
//寻找数组中数值最小的元素
min = a[0];
for(i = 1; i < a.length; i++)
if(a[i] < min) min = a[i];
System.out.println("\n最小数为:" + min);
}
}
程序的运行结果为:
数组元素为: 30 81 37 45 26 46 44 78 80 64
最小数为:26
如果此问题不用数组方法设计,而用简单变量方法设计,程序将非常复杂。因此,数组是复杂问题的程序设计所必需的。
------------------------------------------------------------------------------------------------------
【例2.12】把10个数按从小到大的次序排序。
要求:用数组初始化赋值方法给出10个整数数值,用直接交换排序算法排序。
直接交换排序算法思想:例2.11程序找到的是数组a中的最小数。如果我们在此基础上设计一个循环过程,把每次找到的最小数和数组中尚未排好序的数据元素交换,下次循环时,从这个数据元素的下一个位置开始,继续这样的寻找和交换过程。这样的过程共进行a.length-1次,则全部数组中的数据元素就按从小到大的次序排好了。
程序设计如下:
public class Exam2_12
{
public static void main(String args[])
{
int a[] = {30,81,37,45,26,46,44,78,80,64};
int i, j, min, temp;
System.out.println("排序前数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
//直接交换排序
for(i = 0; i < a.length-1; i++) //循环a.length-1次
{
min = i;
for(j = i+1; j < a.length; j++)
if(a[j] < a[min]) min = j; //寻找最小数
if(min != i) //判断是否需要交换
{
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
}
System.out.println("\n排序后数组元素为:");
for(i = 0; i < a.length; i++)
System.out.print(a[i] + " ");
}
}
程序的运行结果为:
排序前数组元素为:
30 81 37 45 26 46 44 78 80 64
排序后数组元素为:
26 30 37 44 45 46 64 78 80 81
2、二维数组
Java语言只定义了一维数组,但是,如果一维数组的每个数组元素都是一个一维数组,则构成了Java语言的二维数组。和一维数组的使用方法类同,二维数组的使用也分三步:定义数组变量、为数组分配内存单元和使用数组元素。
1.二维数组定义:
二维数组变量定义的一个例子如下:
int a[][];
或
int[] a[];
上面语句定义了一个数据类型为int[](即一维数组类型)、标识符为a的一维数组,即数组a是二维数组。
上述语句执行后数组a的内存状态如下图中的(a)所示:
java1-3.gif
为二维数组变量分配内存单元时必须指定每一维的数组元素个数。
例如:
a = new int[3][3];
就具体分配了包含3个int[3]类型数组元素的内存单元,并把该连续内存单元的首地址赋给数组名a,同时为每个数组元素初始化赋值0。
上图中的(b)就是上述语句执行后的内存示意图。
使用二维数组元素的方法和使用一维数组元素的方法类同,只是这里要指出二维数组的每一维的下标。例如,语句
a[0][0] = 10;
就给数组元素a[0][0]赋了数值10。如上图(c)所示。
2.二维数组简化:
同样,二维数组也可以用简化方法。例如:
int a[][] = new int[5][5];
就在定义int类型的二维数组变量a的同时,为数组分配了内存单元结构如图2.2(b)所示的5个每一维为int[5]类型数组元素的内存空间,并给每个数组元素初始赋值0。
又例如:
int a[][] = {{1,2,3},{4,5,6},{7,8,9}};
就在定义int类型二维数组变量a、并为二维数组动态分配了9个int类型数组元素内存空间的同时,初始化给数组元素a[0][0]赋初值1,a[0][1]赋初值2,a[0][2]赋初值3,a[1][0]赋初值4,……,a[2][2]赋初值9。
三维数组或更多维数组的使用方法和二维数组的使用方法类同。
【例2.13】求C = A×BT,其中,A是一个行向量,BT是一个列向量,C是一个矩阵。例如,设A和B均为n=3的向量,则矩阵C元素的计算方法是:c11=a1*b1,c12=a1*b2,c13=a1*b3,c21=a2*b1,……,c33=a3*b3。
设计思想:这是一个矩阵运算。用一维数组 a存放行向量A,用一维数组 b存放列向量BT,用两维数组存放矩阵C。
程序设计如下:
public class Exam2_13
{
public static void main(String args[])
{
final int n = 3;
int a[] = {1,2,3};
int b[] = {4,5,6};
int c[][] = new int[n][n];
int i, j;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
c[i][j] = a[i] * b[j]; //计算cij
System.out.println (”二维数组元素为:”);
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
System.out.print(c[i][j] + " ");
System.out.println();
}
}
}
程序运行输出结果为:
二维数组元素为:
4 5 6
8 10 12
12 15 18
3、不规则的二维数组
由于Java语言的二维数组是由一维数组定义的,所以,可以把二维数组中的每个一维数组定义为不同的元素个数,这样就可以构成不规则的二维数组。
不规则二维数组的具体设计方法是:先定义一个二维数组变量,并指定第一维的元素个数,然后再分别为第二维数组(即第一维数组的每个数组元素)分配不同的内存单元。由于此时是分别为第二维数组分配内存单元,并且第二维数组所分配的内存单元个数可以是不相同的,因此就构成了不规则的二维数组。
例如,下面的代码先定义一个二维数组,并为数组的第一维数组元素分配空间(这就要求必须指定其具体个数),然后再分别为第二维数组元素分配不同的内存空间。
int twoDim [][] = new int [4][]; //定义二维数组,并指定第一维的元素个数
twoDim[0] = new int[1]; //指定第二维第一个元素的个数
twoDim[1] = new int[2]; //指定第二维第二个元素的个数
twoDim[2] = new int[3]; //指定第二维第三个元素的个数
twoDim[3] = new int[4]; //指定第二维第四个元素的个数
数组twoDim得到的内存单元结构如下图所示:
java1-4.gif
【例2.14】计算并保存九九乘法表,要求重复的部分只保存一个。
设计思想:九九乘法表需要一个二维数组来保存,因为要求重复的部分(如1*2和2*1)只保存一个,所以需要把二维数组定义成不规则的二维数组。
程序设计如下:
public class Exam2_14
{
public static void main(String args[])
{
final int N = 9;
int a[][] = new int [N][]; //定义二维数组,并指定第一维的元素个数
int i,j;
for(i = 0; i < N; i++)
a[i] = new int [i+1]; //指定不规则的第二维的个数
for(i = 0; i < N; i++)
for(j = 0; j <= i; j++)
a[i][j] = (i + 1) * (j + 1); //保存乘法表
//输出乘法表
for(i = 0; i < N; i++)
{
for(j = 0; j <= i; j++)
System.out.print(a[i][j] + " ");
System.out.println();
}
}
}
程序运行输出如下:
1
2 4
3 6 9
4 8 12 16
5 10 15 20 25
6 12 18 24 30 36
7 14 21 28 35 42 49
8 16 24 32 40 48 56 64
9 18 27 36 45 54 63 72 81