《Java第5章数组及应用.ppt》由会员分享,可在线阅读,更多相关《Java第5章数组及应用.ppt(54页珍藏版)》请在三一办公上搜索。
1、第5章数组及应用,内容提要,数组是程序开发中使用最多的数据结构之一。Java语言同样支持数组的使用,与其他语言不同的是Java数组是一种引用数据类型。本章将介绍如何创建和使用数组、数组的数组。,5.1 创建和使用数组,5.1.1 数组定义5.1.2 数组的使用5.1.3 数组元素的复制5.1.4 数组作为方法参数和返回值5.1.5 实例:随机抽取4张牌5.1.6 实例:一个整数栈类5.1.7 可变参数的方法5.1.8 数组的排序5.1.9 数组的查找,5.1 创建和使用数组,数组是几乎所有程序设计语言都提供的一种数据存储结构。所谓数组是名称相同,下标不同的一组变量,它用来存储一组类型相同的数据
2、。,5.1.1 数组定义,下面就来介绍如何声明、初始化和使用数组。使用数组一般需要3个步骤:声明数组:声明数组名称和元素的数据类型。创建数组:为数组元素分配存储空间。数组的初始化:为数组元素赋值。,5.1.1 数组定义,1.数组声明 使用数组之前需要声明,声明数组就是告诉编译器数组名和数组元素类型。数组声明可以使用下面两种等价形式:type arrayName;type arrayName;例如,下面声明了几个数组:double score;String words;Circle circle;,5.1.1 数组定义,2.创建数组数组声明仅仅声明一个数组对象引用,而创建数组是为数组的每个元素分
3、配存储空间。创建数组使用new语句,一般格式为arrayName=new typearraySize;该语句功能是分配arraySize个type类型的存储空间,并通过arrayName来引用。例如:score=new double5;circle=new Circle10;,5.1.1 数组定义,数组的声明与创建可以写在一个语句中,例如:double score=new double5;String words=new String3;当用new 运算符创建一个数组时,系统就为数组元素分配了存储空间,这时系统根据指定的长度创建若干存储空间并为数组每个元素指定默认值。对数值型数组元素默认值是0
4、、字符型元素的默认值是u0000、布尔型元素的默认值是false。如果数组元素是引用类型,其默认值是null。,5.1.1 数组定义,上面两个语句分别分配了5个double型和3个String类型的空间,并且每个元素使用默认值初始化。上面两个语句执行后效果如图5.1所示。,5.1.1 数组定义,数组score的每个元素都被初始化为0.0,而数组words的每个元素被初始化为null。对于引用类型数组(对象数组)还要为每个数组元素分配引用空间,例如:,words0=new String(Java);words1=new String(is);words2=new String(cool);上面语
5、句执行后效果如图5.2所示。,5.1.1 数组定义,声明数组同时可以使用初始化器对数组元素初始化,这种方式适合数组元素较少的情况,这种初始化也称为静态初始化,例如:double score=79,84.5,63,90,98;String words=Java,is,cool;,5.1.1 数组定义,上面两句还可以写成:double score=new double79,84.5,63,90,98;String words=new StringJava,is,cool,;用这种方法创建数组不能指定大小,系统根据元素个数确定数组大小。另外可以在最后一个元素后面加一个逗号,以方便扩充。,5.1.2
6、数组的使用,1.数组元素的使用定义了一个数组,并使用new运算符为数组元素分配了内存空间后,就可使用数组中的每一个元素。数组元素的使用方式是:arrayName index下面程序演示了数组的使用和length成员的使用。程序5.1 ArrayDemo.java,5.1.2 数组的使用,使用增强的for循环如果程序只需顺序访问数组中每个元素,可以使用增强的for循环,它是Java 5新增功能。增强的for循环可以用来迭代数组和对象集合的每个元素。它的一般格式为:for(type identifier:expression)/循环体,5.1.2 数组的使用,该循环的含义为:对expression
7、(数组或集合)中的每个元素identifier,执行一次循环体中的语句。这里,type为数组或集合中的元素类型。expression必须是一个数组或集合对象。下面程序演示了一个元素为字符串的对象数组的使用。,5.1.2 数组的使用,程序5.2 EnhancedForDemo.javapublic class EnhancedForDemopublic static void main(String args)String seasons=Spring,Summer,Fall,Winter;for(String element:seasons)System.out.print(+element)
8、;,5.1.3 数组元素的复制,经常需要将一个数组的元素复制到另一个数组中。首先可能想到使用赋值语句实现。例如原来有一个数组one,其中有4个元素,现在定义一个数组two,与原来数组类型相同,元素个数相同。现在使用下列方法试图将数组one中的每个元素复制到two数组中。int one=10,30,20,40;int two=one;,5.1.3 数组元素的复制,上述两条语句实现对象的引用赋值,两个数组引用指向同一个数组对象,如图5.3所示。要真正实现数组元素的复制可使用下列方法。int one=10,30,20,40;int two=new intone.length;for(int j=0;
9、j one.length;j+)twoj=onej;,5.1.3 数组元素的复制,除了上面的方法外,还可以使用System 类的arraycopy()方法,格式如下:public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)src为源数组,srcPos为源数组的起始下标,dest为目的数组,destPos为目的数组下标,length为复制的数组元素个数。下面代码实现将one中的每个元素复制到数组two中。int one=10,30,20,40;int two=new intone.
10、length;System.arraycopy(one,0,two,0,4);,5.1.3 数组元素的复制,程序5.3 ArrayCopyDemo.java,5.1.4 数组作为方法参数和返回值,1.数组作为方法的参数可以将数组对象作为参数传递给方法,例如下面代码定义了一个求数组元素和的方法。public static double sumArray(double array)double sum=0;for(int i=0;i array.length;i+)sum=sum+arrayi;return sum;,5.1.4 数组作为方法参数和返回值,2.数组作为方法的返回值一个方法也可以返回
11、一个数组对象,例如,下面的方法返回参数数组的元素反转后的一个数组。public static int reverse(int list)/创建一与参数数组大小相同的数组 int result=new intlist.length;for(int i=0,j=result.lenth 1;i list.length;i+,j-)resultj=listi;/实现元素反转 return result;/返回数组,5.1.5 实例:随机抽取4张牌,从一副有52张的纸牌中随机抽取4张,打印出抽取的是哪几张牌。我们可以定义一个有52个元素的名为deck的数组,用0到51填充这些元素。int deck=n
12、ew int52;for(int i=0;ideck.length-1;i+)/填充每个元素 decki=i;设元素值从0到12为黑桃,13到25为红桃,26到38为方块,39到51为梅花。然后打乱每个元素的牌号值(洗牌),之后从中取出前4张牌,最后用cardNumber/13确定花色,用cardNumber%13确定哪一张牌。,5.1.5 实例:随机抽取4张牌,程序5.4 DeckOfCards.java,5.1.6 实例:一个整数栈类,栈是一种后进先出(Last In,First Out,LIFO)的数据结构,在计算机领域应用广泛。例如,编译器就使用栈来处理方法调用。当一个方法被调用时,方
13、法的参数和局部变量被推入栈中,当方法又调用另一个方法时,新方法的参数和局部变量也被推入栈中。当方法执行完返回调用者时,该方法的参数和局部变量从栈中弹出,释放其所占空间。,5.1.6 实例:一个整数栈类,可以定义一个类模拟栈结构。为简单起见,设栈中存放int类型值,StackOfIntegers类的代码如下。程序5.5 StackOfIntegers.java该栈类使用数组实现。元素存储在名为elements的整型数组中,当创建栈对象时将同时创建一个数组对象。,5.1.6 实例:一个整数栈类,使用默认构造方法创建的栈包含10个元素,也可以使用带参数构造方法指定数组初始大小。变量size用来记录栈
14、中元素个数,下标为size-1的元素为栈顶元素。如果栈空,size值为0。StackOfIntegers类实现了栈的常用方法,其中包括push()将一个整数存入栈中;pop()方法元素出栈方法;peek()方法返回栈顶元素但不出栈;empty()方法返回栈是否为空;getSize()方法返回栈中元素个数。,5.1.6 实例:一个整数栈类,程序5.6 StackOfIntegersDemo.javapublic class StackOfIntegersDemo public static void main(String args)StackOfIntegers stack=new Stack
15、OfIntegers();/向栈中存入10个整数 for(int i=10;i 20;i+)stack.push(i);/弹出栈中的所有元素 while(!stack.empty()System.out.print(stack.pop()+);,5.1.7 可变参数的方法,从Java 5开始,允许定义方法(包括构造方法)带可变数量的参数。这种方法称为可变参数(variable argument)方法。具体做法是在方法参数列表的最后一个参数的类型名之后、参数名之前使用省略号,例如:public static double avg(double values)/方法体,5.1.7 可变参数的方法,
16、这里,参数values被声明为一个double型值的序列。其中参数的类型可以是引用类型。对可变参数的方法,调用时可以为其传递任意数量的指定类型的实际参数。在方法体中,编译器将为可变参数创建一个数组,并将传递来的实际参数值作为数组元素的值,这就相当于为方法传递一个指定类型的数组。请看下面例子。,5.1.7 可变参数的方法,程序5.7 VarargsTest.javapublic class VarargsTest public static double avg(double.values)double sum=0;for(int value:values)sum=sum+value;/求数组元
17、素之和 double avg=sum/values.length;return avg;public static void main(String args)System.out.println(avg(60,70,86);,5.1.7 可变参数的方法,该程序定义了一个带可变参数的方法avg(),它的功能是返回传递给该方法的多个double型数的平均值。该程序调用了avg()方法并为其传递3个参数,输出结果为70.2。在可变参数的方法中还可以有一般的参数,但是可变参数必须是方法的最后一个参数,例如,下面定义的方法也是合法的:public static double avg(String na
18、me,double.values)/方法体,5.1.8 数组的排序,在程序设计中,排序是一种常见的工作。例如,一个数组可能存放某个学生的各科成绩,现要求将成绩按从低到高的顺序输出,这就需要为数组排序。排序有多种方法,如选择排序、插入排序等。这里介绍一个简单的选择排序方法(selection sort)。,5.1.8 数组的排序,这种排序的思想是(以升序为例):先取出数组中第一个元素,依次与剩余元素比较,如果逆序,则交换两个元素,第一趟比较可找出最小的元素。接下来取出数组的第二个元素,再依次与剩余元素比较,第二趟比较可找出次小的元素。这样下去,即可将数组中的元素按非递减的顺序排序。程序5.8 S
19、electionSort.java,5.1.9 数组的查找,与排序一样,查找也是计算机程序设计中常见的工作。查找(searching)是在数组中寻找特定元素的过程,例如,判断成绩列表中是否包含某一特定的分数。有很多算法和数据结构用于查找,本节讨论两种常用的算法:线性查找(linear searching)二分查找(binary searching),5.1.9 数组的查找,1.线性查找法线性查找法是将要查找的关键字key与数组中的元素逐个进行比较,直到在数组中找到与关键字相等的元素,或者查完所有元素也没有找到。如果查找成功,线性查找法返回与关键字相等的元素在数组中的下标,如果不成功,则返回-1
20、。下面的linearSearch()方法在数组array中查找关键字keypublic static int linearSearch(int array,int key)for(int i=0;i array.length;i+)if(arrayi=key)return i;return-1;,5.1.9 数组的查找,线性查找法用关键字与数组中的每一个元素进行比较。数组中的元素可以按任意顺序排列。在平均情况下,这种算法需要比较数组中一半的元素。由于线性查找法的执行时间随数组元素个数的增长而线性增长,所以对于大的数组来说其效率不高。2.二分查找法二分查找法是另一种常见的查找法。使用二分查找法的
21、前提条件是数组元素必须已经排序。不失一般性,假设数组按升序排序。二分查找法首先将关键字与数组的中间元素比较,有下面3种情况,5.1.9 数组的查找,如果关键字比中间元素小,那么只需在前一半数组元素中查找。如果关键字和中间元素相等,则查找成功,查找结束。如果关键字比中间元素大,那么只需在后一半数组元素中查找。显然,二分法查找每比较一次就排除数组中一半的元素。假设用low和high分别记录当前查找的数组的第一个和最后一个下标。初始条件下,low为0,high为array.length-1。mid表示数组中间元素的下标,这样mid就是(low+high)/2。,5.1.9 数组的查找,public
22、static int binarySearch(int array,int key)int low=0;int high=array.length-1;while(high=low)int mid=(low+high)/2;if(key arraymid)high=mid-1;else if(key=arraymid)return mid;elselow=mid+1;return low-1;,5.2 多维数组,Java语言中数组元素还可以是一个数组,这样的数组称为数组的数组或多维数组。多维数组的使用也分为声明、创建和初始化3个步骤。,5.2.1 多维数组定义,1.多维数组声明多维数组有下面3
23、种等价的声明格式:type arrayName;type arrayName;type arrayName;这里,type为数组元素的类型,arrayName为数组名。例如,下面语句声明了一个多维数组a和一个多维数组str。int arr;String cities;,5.2.1 多维数组定义,2.创建数组多维数组的创建也是使用new运算符为数组元素分配内存,分配空间的方法有两种。int arr=new int23;这种方法适用于数组的低维具有相同个数的数组元素。在Java中,二维数组是数组的数组,即数组元素也是一个数组。上述语句执行后创建的数组如图5.4所示图中共有3个对象:arr、arr0
24、和arr1。可以使用arr.length得到数组arr的大小,值为2,使用arr0.length得到arr0数组的大小,结果为3。,5.2.1 多维数组定义,对多维数组的初始化,也可以使用默认值初始化。当为数组的每个元素分配了存储空间后,系统使用默认值初始化数组元素,如上述语句执行后,数组arr的6元素值都被初始化为0,图5.4 arr数组元素空间的分配,5.2.2 不规则数组,Java的二维数组是数组的数组,对二维数组声明时可以只指定第一维的大小,第二维的每个元素可以指定不同的大小,例如:String cities=new String2;/cities数组有2个元素cities0=new
25、String3;/cities0数组有3个元素cities1=new String2;/cities1数组有2个元素,5.2.2 不规则数组,这种方法适用于低维数组元素个数不同的情况,即每个数组的元素个数可以不同。对于引用类型的数组,除了为数组分配空间外,还要为每个数组元素的对象分配空间,例如:cities00=new String(北京);cities01=new String(上海);cities02=new String(天津);cities10=new String(伦敦);cities11=new String(纽约);,5.2.2 不规则数组,cities数组元素空间的分配情况如图
26、5.5所示。,5.2.2 不规则数组,对于二维数组也可以使用初始化器在声明数组的同时为数组元素初始化,例如:int arr=15,56,20,-2,10,80,-9,31,76,-3,99,21,;String cities=北京,上海,天津,伦敦,纽约;,5.2.3 数组元素的使用,对于多维数组中每个元素的引用方式为:arrayNameindex1index2其中index1和index2为数组元素下标,可以是整型常数或表达式。同样,每一维的下标也是从0到该维的长度减1。多维数组每一维也都有一个length成员表示数组的长度。对于cities数组,cities.length表示数组citie
27、s的元素个数,其值为2,cities 0.length表示数组cities 0的长度,其值为3。下面例子使用数组求一个矩阵的转置。,5.2.3 数组元素的使用,程序5.9 MatrixTest.java,5.2.4 实例:打印杨辉三角形,杨辉三角形,又称帕斯卡三角形,是二项式系数在三角形中的一种几何排列。下面的程序打印输出前10行杨辉三角形。程序5.10 YangHui.java,5.2.5 实例:矩阵乘法,使用数组还可以计算两个矩阵的乘积。如果矩阵A乘以矩阵B得到矩阵C,则必须满足如下要求:(1)矩阵A的列数与矩阵B的行数相等。(2)矩阵C的行数等于矩阵A的行数,列数等于矩阵B的列数。例如,下面的例子说明两个矩阵是如何相乘的在结果矩阵中,第1行第1列的元素是66,它通过下列计算得来:54+74+82+21=66,5.2.5 实例:矩阵乘法,即若矩阵AmnBnl=Cml,则:其中,Amn表示mn矩阵,cij是矩阵C的第i行j列元素。,5.2.5 实例:矩阵乘法,程序5.11 MatrixMultiple.java,5.3 小 结,数组是类型相同的变量的集合。在Java语言中数组元素可以是基本数据类型,也可以是引用数据类型。使用数组需要声明数组、为数组对象分配存储空间、为数组元素分配存储空间。如果数组元素也是一个数组,则称为数组的数组或多维数组。,