
7-2 数组的声明与应用
7-2-1 数组的声明
在Java中数组的符号是[ ],读者可以将[ ]想成是中括号。数组在使用前需要先声明,声明语法如下。

或是

读者可以将上述数组名想成是数组变量,例如,下面是一系列数组声明的实例。

7-2-2 数组的空间配置
数组声明完成后还不能使用,接着必须为数组配置一定的空间(长度),数组空间配置的语法如下。

例如,要配置double数据类型,数组名是degree,可以容纳7个数据的数组,数组的声明与配置如下。

new是一个关键词,主要功能是配置空间大小(也可称配置数组长度),可以将上述语句解释为可以配置存放7个双精度浮点数的内存空间。当数组声明与配置完成后,数组的名称与空间大小(数组长度)就确定了,未来程序应用时不能再更改数组的空间大小。在使用上,索引值为0~(n-1),由于有7个数据所以索引值是0~6,在存取数据时如果超出此索引值范围,程序会产生异常。
程序实例ch7_2.java:使用数组方式重新设计ch7_1.java。

执行结果
与ch7_1.java相同。
上述程序在执行时经过第6行声明后,内存内建立了数组空间,如下所示。

经过第8~14行设置数组内容后,上述数组的空间内容如下所示。

第15行后就剩下简单的运算了,从上述程序实例读者应该充分体会到使用数组有下列好处。
(1)变量的省略。只使用了一个变量,配合索引值,设置一周温度。
(2)用了一个循环计算总和(15和16行),另一条命令计算平均值(17行),程序精简许多。
(3)程序实例ch7_1.java是一个星期的温度使用7个变量,在多个变量环境下无法使用循环执行计算统计工作。
(4)使用数组让程序设计的扩展性变得很强,例如,如果延伸至计算一个月(30天计)的平均温度,只要将程序第15行和17行的7改为30,其他部分不用变动,就轻松算出平均温度了。
7-2-3 同时执行数组的声明与配置
从7-2-1节和7-2-2节分别执行了数组的声明与配置数组空间,在Java程序设计中可以将这两个工作用一条命令表示。
程序实例ch7_3.java:重新设计ch7_2.java,主要是将数组的声明与配置用一条命令表示。原先第5和6行浓缩成第5行。

执行结果
与ch7_2.java相同。
7-2-4 数组的属性length
在程序实例ch7_3.java中,计算一周温度总和与平均值时特别使用数字7,因为我们知道数组长度是7,如果未来将程序改为计算一个月的平均温度时,需要将7改为30或31,有一些不便利,常常会漏改一些部分造成程序计算错误。在Java中其实数组是一个对象,有一个属性是length,这个属性记录了数组的长度,所以可以充分利用这个属性简化程序设计。
程序实例ch7_4.java:使用数组属性length重新设计ch7_3.java。

执行结果
与ch7_3.java相同。
上述程序使用了下列方式获得数组长度。

此例对象是degree,所以相当于使用degree.length获得了数组长度,后面还会讲解更多对象与属性的相关知识。
7-2-5 数组初值的设置
Java也允许在声明数组时同时设置数组的初值,初值设置时所使用的是大括号“{”“}”。下面将直接以实例说明。
程序实例ch7_5.java:以设置数组初值方式,重新设计ch7_4.java。

执行结果
与ch7_4.java相同。
从上述语句看到当设置数组初值时,可以省略用new运算符声明数组长度,因为建立初值时,已经同时指定了此数组所需的内存空间。同时也可以发现,整个程序变得比较简洁。
7-2-6 特殊数组声明与初值设置
本节会列出一些不常见但是Java可以使用的数组声明与应用。
程序实例ch7_6.java:声明与配置数组时以变量当作数组长度。

执行结果

上述程序的重点是第4行,先设置第3行x变量值,然后在第4行以变量x当作声明数组的长度,所以上述第4行的数组长度是3,第6行是2+2+2,所以总和是6。
程序实例ch7_7.java:声明与配置数组时以表达式当作数组长度。

执行结果

上述程序的重点是第5行,在第3、4行分别设置x、y变量值,然后在第5行以变量y-x当作声明数组的长度,表达式y-x的计算结果就是数组的长度,所以上述经计算后数组长度是2。
程序实例ch7_8.java:声明数组变量时,同时以表达式当作数组初值。

执行结果

上述程序第5行数组z[2]的元素内容声明是x+y表达式,由于第3和4行已经声明了x和y的值分别是3和5,所以经计算后z[2]相当于是8。
7-2-7 常见的数组使用错误——索引值超出数组范围
据笔者多年程序设计经验观察,存取数组最常见的错误是索引值超出声明的范围,这种现象在程序编译时不会出错误,但是在执行时就会有错误产生。
程序实例ch7_9.java:这个程序的数组有三个元素,索引值范围是0~2,但是程序第4行却尝试设置z[3]元素内容。

执行结果

上述第4行的数组索引3超出范围造成异常ArrayIndexOutBoundsException,所以程序终止,其实第5行也是如此,可是程序执行到第4行就中止不再往下编译,所以还看不到第5行的错误。
7-2-8 foreach循环遍历数组
这是一种遍历数组更简洁的for循环,有时候可以表示为for(:),在这个语法下可以不使用数组的长度和索引,然后遍历整个数组。它的语法如下:
for(数据类型变量名称:数组名)
上述数据类型必须与数组名的数据类型相同。程序实例ch7_10.java:遍历数组与输出内容。

执行结果

上述每一轮执行时会从“:”后面的numList数组中取出一个元素,将值设置给num变量,然后执行循环,所以最后可以输出所有数组内容。
程序实例ch7_11.java:计算成绩的平均值。成绩是存储在第3行的score数组。

执行结果

7-2-9 与数组有关的程序实例
当相同类型的数值数据存放在一个数组中时,除了可以计算总和、平均值外,常见的其他应用可找出最大值、最小值、符合特定条件的值,以及重新排列数据。
程序实例ch7_12.java:找出数组的最大值与最小值。

执行结果

程序实例ch7_13.java:第3行定义了score数组,这个数组存储了一系列学生成绩,及格分数变量是passingScore=60分是在第4行定义的,这个程序会列出不及格的学生成绩,同时列出此学生的索引值。

执行结果

接着要讲解数据结构中最基础的应用——数组排序,使用的是气泡排序法(Bubble Sort)。
程序实例ch7_14.java:数组排序的应用,这个程序会将数组由大到小排序。

执行结果

这个程序设计的基本思想是将数组相邻元素做比较,由于是要从大排到小,所以只要发生左边元素值比右边元素值小,就将相邻元素内容对调,由于是5个数据所以每次循环比较4次即可。上述语句所列出的执行结果是每个外层循环的执行结果,下面是第一个外层循环每个内层循环的执行结果。

所以得到了第1次外层循环的执行结果,读者可以将上述结果与执行结果的第1行输出做比较。下面是第2个外层循环每个内层循环的执行结果。

所以得到了第2次外层循环的执行结果,读者可以将上述结果与执行结果的第2行输出做比较。另外,读者应该发现在上述程序设计中,当执行完第一次外层循环时最小值已经在最右边了,所以第2次外层循环的第4次内层循环的比较是多余的,这个思想可以应用到第3次或第4次外层循环。下面是第3个外层循环每个内层循环的执行结果。

所以得到了第3次外层循环的执行结果,读者可以将上述结果与执行结果的第3行输出做比较。下面是第4个外层循环每个内层循环的执行结果。

所以得到了第4次外层循环的执行结果,读者可以将上述结果与执行结果的第四行输出做比较。从上述执以看到程序实例ch7_14.java的内层循环比较有些是多余的,如果设计程序想要提高效率,次内层循环比较时少比较一次,这样就可以提高效率了。
程序实例ch7_15.java:以更有效率的方式重新设计ch7_14.java,主要思想是每一次内层循环的比较会少一次。

执行结果
与ch7_14.java相同。
上述程序的重点是“score.length–i–1”,i是外层循环的索引变量,当i等于0时,相当于是内层循环执行次数不变,当i值每次增加1时内层循环执行次数就少一次,意义是可以少比较一次,如此就可以达到提高效率的目的了。