Java从入门到精通(微视频精编版)
上QQ阅读APP看书,第一时间看更新

第5章 数组应用

视频讲解:56分钟

数组是最为常见的一种数据结构。数组中的元素拥有相同的类型,用一个标识符封装到一起的数据序列,这个数据序列可以是基本类型,也可以是对象类型。可以用一个统一的数组名和下标来访问数组中的单个指定元素。实质上数组是一个简单的线性序列,因此数组访问起来很快。本堂课将向读者介绍有关数组的知识。

学习摘要:

 一维数组创建和使用

 二维数组创建和使用

 遍历数组

 对数组进行排序

5.1 一维数组的创建与应用

视频讲解

数组是具有相同数据类型的一组数据的集合。比如,球类的集合:足球、篮球、羽毛球等;电器集合:电视机、洗衣机、电风扇等。在程序设计中,可以将这些集合称为数组。数组中的每个元素具有相同的数据类型。在Java中将数组同样看作是一个对象,虽然基本数据类型不是对象。但是由基本数据类型组成的数组则是对象。在程序设计中引入数组可更有效地管理和处理数据。可根据数组的维数将数组分为一维数组、二维数组、多维数组。

说明

对象是一种复合数据,在之后的课程中讲解面向对象编程时,会详细地讲解类与对象。

5.1.1 创建一维数组

数组作为对象允许使用new关键字进行内存分配。在使用数组之前,必须先定义数组变量所属的类型,即声明数组。

语法:数组类型 数组名[];

数组类型[] 数组名;

参数:数组类型用于决定数组元素的数据类型。它可以是Java中任意的数据类型,包括基本数据类型和对象类型。数组名必须是一个合法的标识符。符号“[]”指明该变量是一个数组类型变量。单个“[]”表示要创建的数组是一个一维数组。例如声明一维数组的关键代码如下。

声明数组后,还不能访问它的任何元素。因为声明数组仅仅是给出了数组名字和类型,要想真正使用数组还要为它分配内存空间。在为数组分配内存空间时必须指明数组的长度。为数组分配内存空间的格式如下。

语法:数组名字 = new数组类型[数组长度];

参数:数组名字是数组变量的名称。数组长度用于指定数组中成员的个数,即数组的大小。

通过上面的语法可知使用new关键字来分配数组时,必须指定数组的类型和数组长度,即数组的大小。例如:

int[] arr = new int[5];

以上代码表示要创建长度为5的整型数组。并且将创建的数组对象赋给引用变量arr,即引用变量arr引用这个数组,如图5.1所示。

图5.1 一维数组的内存分配示意图

在图5.1中arr为数组名称,方括号“[]”中的值为数组的下标。数组通过下标来区分数组中不同的元素。数组的下标是从0开始的。由于创建的数组arr中有5个元素,因此数组中的元素的下标为0~4。

说明

使用new关键字为数组分配内存时,整型数组中的各个元素的初始化值都为0。

也可以在声明数组的同时为数组分配内存,这种创建数组的方式是将数组的声明和内存的分配和在一起执行。

语法:数组元素类型 数组名 = new数组元素类型[数组元素的个数];

例如:创建数组month,并指定了数组长度是12的代码如下。

int month[] = new int[12]

5.1.2 初始化一维数组

数组可以与基本数据类型一样进行初始化操作。数组的初始化可分别为数组中每个元素赋值。数组的初始化有两种方式:第一种初始化方式如下。

第二种数组初始化方式如下。

数组的初始化就是在大括号之内用逗号分开的表达式列表,逗号分开了数组元素的值,系统会根据数据类型自动为数组分配一定的内存空间。

5.1.3 遍历一维数组

在Java集合中一维数组是常见的一种数据结构。下面的实例是使用一维数组将1~12月各月的天数输出。

【例5.1】 在项目中创建类GetDay,在主方法中创建int型数组,并实现将各月的天数输出。(实例位置:资源包\源码\05\5.01)

运行的结果如图5.2所示。

图5.2 实例运行结果

5.2 二维数组的创建与应用

视频讲解

如果一维数组中的每个元素保存的都是一个数组对象,那么它就是一个二维数组。二维数组常用于表示表,表中的信息以行和列的形式组织,第一个下标代表元素所在的行,第二个下标代表元素所在的列。

5.2.1 创建二维数组

二维数组可以看作是特殊的一维数组,因此二维数组的创建同一位数组类似。声明二维数组的语法如下。

数组元素类型 数组名字[][];

数组元素类型[][] 数组名字;

例如:

int myarr[][];

二维数组可以表示一个平面表格的数据,第一维数组的下表可以看作表格的行,第二维数组下表可以看作表的列,如图5.3所示。

图5.3 二维数组

同一维数组一样,二维数组在声明时也没有分配内存空间。同样要使用关键字new来分配内存,然后才可以访问每个元素。

对于多维数组有两种为数组分配内存的方式。

(1)直接为二维数组分配内存空间。例如:

a = new int[2][4]

上述代码创建了二维数组a,二维数组a中包括两个长度为4的一维数组,内存分配如图5.4所示。

图5.4 二维数组内存分配图

(2)可分别为每一维数组分配内存。例如:

a = new int[2][];
a[0] = new int[2];
a[1] = new int[3];

第二种方式同第一种实现的功能相同。使用这种方式为二维数组分配内存时,首先指定第一维数组的内存。然后单独给第二维数组分配内存。通过第二种方式为二维数组分配内存,内存分配如图5.5所示。

图5.5 二维数组内存分配

5.2.2 初始化二维数组

二维数组的初始化同一维数组初始化类似,同样可以使用大括号“{ }”完成二维数组的初始化,不同的是每个二维数组的元素使用大括号定义的一个新的一维数组,即一维数组的每个元素又是一个新的一维数组,语法如下。

type:数组数据类型。

arrayName:数组名称,一个合法的标识符。

value:数组中各元素的值。

例如:初始化二维数组,实例代码如下。

int myarr[][] = {{12,0},{45,10}};

初始化二维数组后,要明确数组的下标都是从0开始。如上面的代码中myarr[1][1]的值为10。

int型二维数组是以int myarr[][]定义,所以可以直接给myarr[x][y]赋值。例如给myarr[1]的第2个元素赋值的代码如下。

myarr[1][1] = 20;

5.2.3 遍历二维数组

二维数组在实际应用中非常广泛。下面的实例就是使用二维数组输出一个3行4列,并且所有元素值都是字符“*”,它们将组成一个矩阵。

说明

对于整型二维数组,创建成功之后系统会给数组中每个元素的初始化值0。

【例5.2】 在主方法中编写代码,使用两层循环实现输出一个3行4列矩阵。(实例位置:资源包\源码\05\5.02)

实例运行结果如图5.6所示。

图5.6 实例运行结果

5.3 多维数组的创建

视频讲解

所谓多维数组就是二维和大于二维的数组,在Java中并不直接支持多维数组(包括二维数组)。多维数组的声明是使用一维数组的嵌套声明实现的。就像二维数组,实际上是一个一维数组的每个元素又被声明为一维数组而构成的二维数组,可以说二维数组是特殊的一维数组。虽然,二维数组也是多维数组,但是实际开发中也有使用三维数组的情况,本节将以三维数组为例,为读者介绍多维数组。

5.3.1 数组创建

多维数组的创建与可以参考二维数组,例如二维数组由两个方括号“[]”定义,那么三维数组或多维数组就由3个或多个方括号“[]”声明,语法如下。

类型 数组名 [][][];

其中3个方括号“[]”分别对应第一维数组长度、第二维数组长度和第三维数组长度。例如:

int array[2][3][3];

二维数组可以看作平面的表格,而三维数组能够表示立体的数据,如图5.7所示。

图5.7 三维数组示意图

5.3.2 初始化数组

和一维二维数组的初始化方法类似。同样可以使用大括号“{}”完成三维数组的初始化,不同的是要使用3层大括号“{}”,第一层定义第一维数组,第二层定义第二维数组,第三层定义第三维数组。语法如下。

type:数组数据类型。

arrayName:数组名称,一个合法的标识符。

value:数组中各元素的值。

例如:

或者:

5.3.3 遍历三维数组

三维数组要使用3层循环来遍历。遍历时,可以使用array[z][x][y]的格式指定数组下标来引用数组元素,数组下标从0开始。例如“array[1][0][0] = 97;”语句,把array[1][0][0]即原有内容7替换为97。

【例5.3】 使用3层for循环遍历输出三维数组内容。(实例位置:资源包\源码\05\5.03)

实例在遍历数组的最内层以循环控制变量k控制的循环中输出数组每个元素的内容,它的上层由循环控制变量j控制的循环在循环体的最后输出换行,使输出内容更加工整。

其中每个循环体都使用了length()方法,该方法用于获取数组的长度,array.length()方法判断第一维数组的长度,array[0].length方法是判断下标为0的第二维数组的长度,因为本实例使用的数组是长短相同的规则数组,所以第一个二维数组即是其他同等级二维数组的长度,则array[0][0].length方法就可想而知,运行结果如图5.8所示。

读者可以尝试在每层循环中的循环体开始或结束的位置添加输出语句,输出读者能辨识的标识,然后多次运行本实例,有助于加强读者对多维数组的结构和遍历原理的理解。

例如,在第一层循环体开始位置添加如下语句。

System.out.println("三维数组第" +(i + 1)+ "个元素是一个" + array[0].length + "维数组,其内容如下:");

那么输出内容就会编程如图5.9所示。

图5.8 实例运行结果

图5.9 添加代码后的实例运行结果

5.4 实战

视频讲解

5.4.1 使用冒泡排序注

冒泡排序法是数组排序算法中比较简单且常用的,它的排序方法类似于冒泡动作,所以起名为冒泡排序法。另外,这也是学校考试和公司面试的常见考题。对于学习程序算法来说冒泡排序是一个很好的入门题目。下面通过实例实现冒泡算法的应用,运行结果如图5.10所示。(实例位置:资源包\源码\05\实战\01)

5.4.2 使用直接选择排序法

直接选择排序法是选择排序的一种,直接选择排序法的交换次数要比冒泡排序法的少,所以直接选择排序比冒泡排序快。下面的实例中使用直接选择排序法对数组进行排序,它也是数组常见的应用,运行结果如图5.11所示。(实例位置:资源包\源码\05\实战\02)

图5.10 实例运行结果

图5.11 实例运行结果

5.4.3 使用快速排序法

快速排序(QucikSort)是对气泡排序的一种改进,其排序速度相对较快。本实例演示如何使用快速排序法对一维数组进行排序,实例中首先定义了一个乱序的字符数组,然后分别把原有数组内容与排序好的数组内容输出到控制台中,运行结果如图5.12所示。(实例位置:资源包\源码\05\实战\03)

图5.12 使用快速排序法对一维数组进行排序

5.4.4 反转数组中元素的顺序

顾名思义,反转数组就是以相反的顺序把原有数组的内容重新排序。反转排序算法在程序开发中也经常用到。下面通过实例来介绍反转排序的具体用法,运行结果如图5.13所示。(实例位置:资源包\源码\05\实战\04)

图5.13 实例运行结果

5.4.5 利用数组随机抽取幸运观众

在电视节目中,经常看到随机抽取幸运观众。如果观众抽取得范围较少,可以让程序使用数组实现,而且效率很高。下面介绍实现的方法:首先将所有观众姓名生成数组,然后获得数组元素的总数量,在数组元素中随机抽取元素的下标索引,根据抽取的下标获得数组的元素作为幸运观众,运行结果如图5.14所示。(实例位置:资源包\源码\05\实战\05)

图5.14 实例运行结果