1、1,第5章,数组与字符串,2,通过本章的学习,主要掌握以下知识点:数组的基本概念 数组元素的访问 栈内存和堆内存 多维数组 字符串 本章的重点:数组的定义与访问 本章的难点:栈内存和堆内存多维数组的定义与应用,3,在程序设计中,数组是常用的数据结构。无论是在面向对象的程序设计中,还是 面向过程的程序设计中,数组都起着重要的作用。从数组的构成形式上可以分为一维数组和多维数组。,4,5.1 数组的基本概念,所谓数组就是相同数据类型的元素按一定顺序排列的集合。在Java中数组元素可以由简单数据类型的量组成,也可以由对象组成。数组中的每个元素都具有相同的数据类型,可以用一个统一的数组名和一个下标来惟一
2、地确定数组中的元素。,5,为了充分地理解数组的概念,首先介绍一下Java有关内存分配的知识。Java把内存分为两种:栈内存、堆内存和static内存。 在方法中定义的一些基本类型的变量和对象的引用变量都在方法的栈内存中分配,当在一段代码块中定义一个变量时,Java就在栈内存中为这个变量分配内存空间,当超出变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。,6,堆内存用来存放由new运算符创建的对象和数组,在堆中分配的内存,由Java虚拟机的自动垃圾回收器来管理。在堆中创建了一个数组或对象后,还可以在栈中定义一个特殊的变量,让栈中的这个变量的取值等于数组
3、或对象的在堆内存中的首地址,栈中的这个变量就成了数组或对象的引用变量,引用变量实际上保存的是数组或对象在内存中的地址(也称为对象的句柄),以后就可以在程序中使用栈的引用变量来访问堆中的数组或对象。引用变量就相当于是为数组或对象起的一个名称。,7,总的来说,数组主要有如下几个特点。 数组是相同数据类型的元素的集合; 数组中的各元素是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起; 数组元素用整个数组的名字和它自己在数组中的顺序位置来表示。例如,a0表示名字为a的数组中的第一个元素,a1代表数组a的每二个元素,依次类推。,8,一维数组是最简单的数组,其逻辑结构是线性表。要使用一维数组,需
4、要经过定义、初始化和应用等过程。,5.2 一维数组,9,5.2.1 一维数组的定义,在使用Java的数组,一般要经过三个步骤:一是声明数组,二是创建空间,三是创建数组元素并赋值。前两个步骤的语法如下:数据类型 数组名; /声明一维数组 数组名=new 数据类型个数; /分配内存组数组,10,数组声明之后,接下来便是要分配数组所需的内存,这时必须用运算符new,其中“个数”是告诉编译器,所声明的数组要存放多少个元素,所以“new”运算符是通知编译器根据括号里的个数,在内存中分配一块空间供该数组使用。,11,下面举例来说明数组的定义,如: int x; x=new int10; 在声明数组时,也可
5、以将两个语句合并成一行,格式如下: 数据类型 数组名 = new 数据类型个数; 如: int x= new int 10;,12,5.2.2一维数组元素的访问,要想使用数组里的元素,可以利用数组名和下标来实现。数组元素的引用方式为: 数组名下标 其中“下标”可以是整型数或表达式。如a3+i(i为整数)。Java数组的下标是从0开始的。如: int x= new int 10; 其中x0代表数组中第1个元素,x1代表第2个元素,x9为第10个元素,也就是最后一个元素。,13,【例5.1】声明一个一维数组,其长度为5,利用循环对数组元素进行赋值,然后再利用另一个循环逆序输出数组元素的内容。程序代
6、码如下:,14,/app5_1.java 一维数组 public class app5_1 public static void main(String args )int i;int a; /声明一个数组aa=new int5; /分配内存空间供整型数组a使用,其元素个数为5for(i=0;i=0;i-) /逆序输出数组的内容System.out.print(“a”+i+”=”+ai+”,t”);System.out.println(“n数组a的长度是:”+a.length); ,【例5.1】续,15,该程序的运行结果如下: a4=4, a3=3, a2=2, a1=1, a0=0 数组a的
7、长度是:5,【例5.1】续,16,5.2.3 一维数组的初始化及应用,对数组元素的赋值,既可以使用单独方式进行(如上例),也可以在定义数组的同时就为数组元素分配空间并赋值,也称为对数组的初始化。其格式如下: 数据类型 数组名=初值0,初值1,初值n; 如: int a=1,2,3,4,5;,17,【例5.2】设数组中有n个互不相同的数,不用排序求出其中的最大值和次最大值。 /app5_2.java 比较数组元素值的大小 public class app5_2 public static void main(String args )int i,Max,Sec;int a=8,50,20,7,8
8、1,55,76,93; /声明数组a,并赋初值if (a0a1)Max=a0; / Max存放最大值Sec=a1; / Sec存放次最大值elseMax=a1;Sec=a0;,18,System.out.print(“数组的各元素为:”+a0+” “+a1);for(i=2;iMax) /判断最大值Sec=Max; /原最大值降为次最大值Max=ai; /ai为新的最大值else /即ai不是新的最大值,但若ai大于次最大值if (aiSec) Sec=ai; /ai为新的次最大值System.out.print(“n其中的最大值是:”+Max); System.out.println(“ 次
9、最大值是:”+Sec); ,【例5.2】续,19,该程序运行结果为: 数组的各元素为:8 50 20 7 81 55 76 93 其中的最大值是:93 次最大值是:81,【例5.2】续,20,5.3 foreach语句与数组,foreach语句只需提供三个数据:元素类型、循环变量的名字(用于存储连续的元素)和用于从中检索元素的数组。foreach的语句语法格式如下: for (type element : array) System.out.println(element); 功能是每次从数组array中取出一个元素,自动赋给element,用户不用判断是否超出了数组的长度。需要注意的是ele
10、ment的类型必须与数组array中元素的类型相同,21,例:int arr=1,2,3,4,5;for (int element : arr)System.out.println(element);,22,5.4 多维数组,虽然一维数组可以处理一般简单的数据,但是在实际的应用中仍显不足,所以Java提供了多维数组。但在Java中并没有真正的多维数组,所谓多维数组只是数组的数组。,23,5.3.1 二维数组,二维数组的声明方式与一维数组类似,内存的分配也一样是用new运算符。 声明与分配内存的格式如下所示: 数据类型 数组名;/声明引用变量 数组名 = new 数据类型行数列数;/分配对象空间
11、数据类型 数组名= new 数据类型 行数列数;/ 引用变量、数组对象,24,例: int a=new int34;,25,Java的多维数组不一定是规则的矩阵形式,如图5.5所示。,26,如:int x;x=new int3; 这两句代码表示数组x有三个元素,每个元素都是int类型的一维数组。相当于定义了三个数组引用变量,分别是int x0,int x1和int x2,完全可以把x0当作一个普通的变量名。另外int x0,int x1这两个数组引用变量只是书写方式不同而已,其作用是一样的,目的就是帮助读者把x1当成一个普通变量名来理解。,27,由于x0、x1和x2都是数组引用变量,必须对它们
12、赋值,指向真正的数组对象,才可以引用这些数组中的元素。 x0=new int 3; x1=new int2; 由此可以看出,x0和x1的长度可以是不一样的,数组对象中也可以只有一个元素。程序运行到这之后的内存分配情况如图5.6所示。,28,29,如果想直接在声明二维数组时就给数组赋初值,可以利用花括号实现,只要在数组的声明格式后面再加上初值的赋值即可。其格式如下:数据类型 数组名=第1行初值,第2行初值, ,第n+1行初值 ;,30,【例5.4】计算并输出杨辉三角形。,/app5_4.java 维数组应用的例子:显示杨辉三角形 public class app5_4 public static
13、 void main(String args )int i,j;int Level=7;int iaYong =new intLevel;System.out.println(“杨辉三角形”);for (i=0;iiaYong.length;i+)iaYongi=new int i+1; iaYong00=1;,31,for (i=1;iiaYong.length;i+) /计算杨辉三角形iaYongi0=1;for (j=1;j iaYongi.length-1;j+)iaYongij=iaYongi-1j-1+iaYongi-1j;iaYongi iaYongi.length-1=1;fo
14、r(i=0;i iaYong.length;i+) /显示出杨辉三角形for(j=0;j iaYongi.length;j+)System.out.print(iaYongij+” ”);System.out.println(); ,【例5.4】续,32,该程序的运行结果为: 杨辉三角形 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 1 6 15 20 15 6 1,【例5.4】续,33,5.3.2 三维以上的多维数组,要想提高数组的维数,只要在声明数组的时候将下标与中括号再加一组即可。 所以三维数组的声明为int a; 而四维数组为int a; 依次
15、类推,34,5.4 字符串,字符串也是编程中经常要使用的数据结构,它是字符的序列,从某种程度上说有些类似于字符数组。 对象,35,5.4.1字符串变量的创建,声明字符串变量的格式与其他变量一样,分为对象的声明与对象创建两步,这两步可以分成两个独立的语句,也可以在一个语句中完成。 格式一: String ;/声明 引用变量 =new String(”字符串”);/生成 对象例: String s; s=new String(”Hello”);,36,上述的两个语句也可以合并成一个语句。其格式如下: 格式二: 引用变量、对象生成 合并为一句 String =new String(”字符串”);例:
16、String s=new String(”Hello”);,37,格式三:兼容C语言 String =”字符串”;例:String s=”Hello”;,38,字符串的连接“字符串1”+ “字符串2”例:String str=“Hello”+”Java”;字符串+其他类型变量自动将其他类型的数据转换成字符串String.valueOf (parameter); 例:int i=10; String s=“i=”+i; /问:S的值是?System.out.println(“s=”i);,str,39,5.4.2 String类的常用方法,Java为String类定义了许多方法。可以通过下述格式
17、调用Java定义的方法: .; 表5.1列出了String类的常用方法。,40,表5.1 String类的常用方法,41,【例5.6】判断回文字符串。 回文是一种“从前往后读”和“从后往前读”都相同的字符串,例如:“rotor”就是一个回文字符串。在本例中使用了两种算法来判断回文字符串。 程序中比较两个字符时,使用关系运算符“=”,而比较两个字符串时,则需使用 equals()方法。程序代码如下: 例: String str1=new String(“JAVA”);String str2=“JAVA”;System.out.println(str1= =str2);/问:结果? System.
18、out.println(?);/问如何使用equals()? str1.equals(str2); 结果? str2.equals(str1);,42,例:/app5_6.java 字符串应用:判断回文字符串 public class app5_6 public static void main(String args)String str=”rotor”;int i=0,n;boolean yn=true;if (args.length0)str=args0;System.out.println(“str=”+str);n=str.length();char schar,echar;whil
19、e (yn ,【例5.6】续,43,if (schar=echar)i+;elseyn=false;System.out.println(“算法1:”+yn);String temp=”,sub1=”;for (i=0;in;i+)sub1=str.substring(i,i+1); /将str的第i个字符载取下来赋给sub1temp=sub1+temp; /将载下来的字符放在字符串temp的首位置System.out.println(“temp=”+temp);System.out.println(“算法2:”+str.equals(temp); ,【例5.6】续,String str=“hello”; str.substring(0,3); /hel str.substring(0,2); /he str.substring(2,4); /问结果?,44,程序可以是带命令行参数。若在命令行方式下输入“java app5_6 hello”,则程序的运行结果如下: str=hello schar=h echar=o 算法1:false temp=olleh 算法2:false,【例5.6】续,45,END,谢谢观看!,