第四章数组与字符串.ppt
,第四章 数组与字符串,概念,数组是一组同类型的变量或对象的集合数组的类型可以是基本类型,或类和接口数组中每个元素的类型相同引用数组元素通过数组名下标数组下标(数组的索引)从0开始数组是一种特殊的对象(Object)定义类型(声明)创建数组(分配内存空间):new一维数组、多维数组,一维数组,一维数组的元素只有一个下标变量例:A1,c3一维数组的声明方法1:类型 数组名;String args;int a;double amount;char c;方法2:类型 数组名;String args;int a;double amount;char c;注意类型是数组中元素的数据类型(基本和构造类型)数组名是一个标识符数组声明后不能被访问,因未为数组元素分配内存空间,double d;System.out.println(d0);,一维数组,数组的创建用new来创建数组为数组元素分配内存空间,并对数组元素进行初始化格式:数组名=new 类型数组长度例:a=new int3;声明和创建的联用:int a=new int3;默认赋初值整型初值为0 int i=new int3;实型初值为0.0 float f=new float3;布尔型初值为false boolean b=new boolean3;,一维数组,一维数组的初始化方式一:在声明数组的同时对数组初始化格式:类型 数组名=元素1,元素2;int a=1,2,3,4,5;方式二:声明和创建数组后用new对数组初始化形式如下:数组名=new 类型标识符数组长度例如:int intArray;intArray=new int3一维数组的引用 数组名下标 下标可以为整型常数或表达式Java对数组元素要进行越界检查以保证安全性。同时,对于每个数组都有一个属性length指明它的长度,例如:a.length指明数组a的长度,【示例4-1】ArrayTest.java演示Java语法定义数组和引用数组元素的方式,public class ArrayTest public static void main(String args)int i;int a=new int5;for(i=0;i=0;i-)System.out.println(a+i+=+ai);,程序运行结果:a4=4 a3=3 a2=2 a1=1 a0=0,【示例4-2】classFibonacci.java,public class ClassFibonacci public static void main(String args)int i;int f=new int10;f0=f1=1;for(i=2;i10;i+)fi=fi-1+fi-2;for(i=1;i=10;i+)System.out.println(F+i+=+fi-1);,程序运行结果:F1=1 F2=1 F3=2 F4=3 F5=5 F6=8 F7=13 F8=21 F9=34 F10=55,多维数组,数组的数组Arrays of Arrays例:表格(行和列)以二维数组为例,二维数组,二维数组的声明类型 数组名,例 int a;数组声明后不能被访问,因未为数组元素分配内存空间二维数组的创建方法一:直接分配空间例 int a=new int23;a00 a01 a02 a10 a11 a12两个一维数组,每个数组包含3个元素,二维数组,二维数组的创建方法二:从最高维开始,为每一维分配空间例 int c=new int2;c0=new int4;c1=new int3;c00 c01 c02 c03 c10 c11 c12 注:为数组分配空间需指定维数大小,至少最高维(最左边)大小错误:int b=new int;,二维数组,二维数组的初始化每个元素单独进行赋值class Test public static void main(String args)int a=new int33;a00=1;a11=1;a22=1;System.out.println(“数组a:”);for(int i=0;i a.length;i+)for(int j=0;jai.length;j+)System.out.print(aij+“”);System.out.println();,最高维数组长度,1 0 00 1 00 0 1,二维数组,二维数组的初始化声明数组的同时初始化 例 int a=1,2,3,3,4,5;a00=1 a01=2 a02=3 a10=3 a11=4 a12=5对数组元素的引用数组名下标1 下标2下标为非负的整型常数,【示例4-3】MatrixMultiply.java,public class MatrixMultiply public static void main(String args)int i,j,k;int a=new int23;int b=1,5,2,8,5,9,10,-3,2,7,-5,-18;int c=new int24;for(i=0;i2;i+)for(j=0;j3;j+)aij=(i+1)*(j+2);for(i=0;i2;i+)for(j=0;j4;j+)cij=0;for(k=0;k3;k+)cij+=aik*bkj;/矩阵相乘,【示例4-3】MatrixMultiply.java,System.out.println(n*MatrixA*);for(i=0;i2;i+)for(j=0;j3;j+)System.out.print(aij+);System.out.println();System.out.println(n*MatrixB*);for(i=0;i3;i+)for(j=0;j4;j+)System.out.print(bij+);System.out.println();System.out.println(n*MatrixC*);for(i=0;i2;i+)for(j=0;j4;j+)System.out.print(cij+);System.out.println();,程序运行结果:*MatrixA*2 3 4 4 6 8*MatrixB*1 5 2 8 5 9 10-3 2 7-5-18*MatrixC*25 65 14-65 50 130 28-130,【示例4-4】TwoArrayAgain.java】不规则数组示例,public class TwoArrayAgainpublic static void main(String args)int twoArray=new int4;/声明二维数组twoArray0=new int1;/定义每一行twoArray1=new int2;twoArray2=new int3;twoArray3=new int4;int i,j,k=0;for(i=0;itwoArray.length;i+)for(j=0;jtwoArrayi.length;j+,k+)twoArray ij=k;for(i=0;itwoArray.length;i+)for(j=0;jtwoArrayi.length;j+)System.out.print(twoArrayij+);System.out.println();,程序运行结果:0 1 2 3 4 5 6 7 8 9,对数组对象的操作(Arrays)java.util.Arrays,全部是静态方法public static int binarySearch(type a,type key)public static int binarySearch(type a,int fromIndex,int toIndex,type key)public static boolean equals(type a,type a2)public static void fill(type a,type val)public static void fill(type a,int fromIndex,int toIndex,type val)public static void sort(type a)public static void sort(type a,int fromIndex,int toIndex)public static void type copyOf(type original,int newLength)public static void type copyOfRange(type original,int from,int to)Public static String toString(type a),boolean,char,type,short,int,long,double,floatObject,注意:Arrays类处于java.util包下,为了在程序中使用Arrays类,必须在程序中导入java.util.Arrays类,示例4-5】UsingArrays.javaimport java.util.*;public class UsingArrays public static void main(String args)/定义一个a数组int a=new int3,4,5,6;/定义一个a2数组int a2=new int3,4,5,6;/a数组和a2数组的长度相等,每个元素依次相等,将输出trueSystem.out.println(a数组和a2数组是否相等:+Arrays.equals(a,a2);/通过复制a数组,生成一个新的b数组int b=Arrays.copyOf(a,6);System.out.println(a数组和b数组是否相等:+Arrays.equals(a,b);/输出b数组的元素,将输出3,4,5,6,0,0System.out.println(b数组的元素为:+Arrays.toString(b);/将b数组的第3个元素(包括)到第5个元素(不包括)赋为1Arrays.fill(b,2,4,1);/fill方法可一次对多个数组元素进行批量赋值/输出b数组的元素,将输出3,4,1,1,0,0System.out.println(b数组的元素为:+Arrays.toString(b);/对b数组进行排序Arrays.sort(b);/输出b数组的元素,将输出0,0,1,1,3,4System.out.println(b数组的元素为:+Arrays.toString(b);,程序运行结果:a数组和a2数组是否相等:truea数组和b数组是否相等:falseb数组的元素为:3,4,5,6,0,0b数组的元素为:3,4,1,1,0,0b数组的元素为:0,0,1,1,3,4,不规则数组-Java语法支持方便地构造一个“不规则”数组,即数组的每一行有不同的长度。,【示例4-4】TwoArrayAgain.javapublic class TwoArrayAgainpublic static void main(String args)int twoArray=new int4;/声明二维数组twoArray0=new int1;/定义每一行twoArray1=new int2;twoArray2=new int3;twoArray3=new int4;int i,j,k=0;for(i=0;itwoArray.length;i+)for(j=0;jtwoArrayi.length;j+,k+)twoArray ij=k;for(i=0;itwoArray.length;i+)for(j=0;jtwoArrayi.length;j+)System.out.print(twoArrayij+);System.out.println();,程序运行结果:0 1 2 3 4 5 6 7 8 9,字符串操作类,java.lang.String类字符串/字符序列构造方法public String()public String(byte bytes)public String(bytebytes,intoffset,intcount)public String(char value)public String(charvalue,intoffset,intcount)public String(Stringoriginal),4.2.1 String类,当创建一个String对象时,被创建的字符串是不能被改变的。每次需要改变字符串时都要创建一个新的String对象来保存新的内容。原始的字符串不变。一个字符串对象一旦被配置,它的内容就是固定不可变的.例如:String str=hello,Java;,4.2.1 String类,String str=Hello;str=Java;。,在Java 中,使用“=”将一个字符串对象指定给一个变量名称,其意义为改变该名称所引用的对象,原来被引用的字符串对象若没有其他名称来引用它,就会在适当的时候被Java 的“垃圾回收”(Garbage Collection)机制回收。在Java 执行时会维护一个String 池(Pool)。对于一些可以共享的字符串对象,会先在String 池中查找是否存在相同的String 内容(字符相同),如果有就直接返回,而不是直接创造一个新的String 对象,以减少内存的耗用。如果在程序中使用下面的方式来声明,则实际上是指向同一个字符串对象:String str1=ByTheWay;String str2=ByTheWay;System.out.println(str1=str2);,如果要比较两个字符串对象的字符值是否相同,要使用equals()方法,以下的写法才会显示true 的结果:String str1=new String(caterpillar);String str2=new String(caterpillar);System.out.println(str1.equals(str2);,1.String对象的创建,(1)String(),默认构造方法,无参数 String s1=new String();(2)String(char chars),传入字符数组 char myChars=a,b,c;String s2=new String(myChars)/使用字符串“abc”初始化s2(3)String(char chars,int startIndex,int numChars),传入一个字符数组,从指定下标位置开始获取指定个数的字符,用这些字符来初始化字符串变量。char myChars=h,e,l,l,o;String s3=new String(myChars,1,3);/使用字符串“ell”初始化s3(4)String(String strObj),传入另一个字符串对象,用该字符串对象的内容初始化 String s4=new String(s3);/这是s4也是“ell”了。(5)String(byte asciiChars)String(byte asciiChars,int startIndex,int numChars)尽管Java的char类型使用16位(bit)表示Unicode编码字符集,在Internet中,字符串的典型格式使用由ASCII字符集构成的8位数组,因为8位ASCII字符串是共同的,当给定一个字节(byte)数组时,String类提供了上面两个初始化字符串的构造函数。;,【示例4-6】:SubStringConv.java,public class SubStringConv public static void main(String args)byte ascii=65,66,67,68,69,70;String s1=new String(ascii);System.out.println(s1);String s2=new String(ascii,2,3);System.out.println(s2);程序运行结果:ABCDEFCDE,2.String对象的连接,与大多数程序语言一样,Java允许使用符号+把两个字符串连接(concatenate)在一起。String word1=Expletive;String word2=deleted;String Message=word1+word2;上面的代码给字符串变量Message赋值为”Expletivedeleted”,。当连接一个字符串和一个非字符串时,后者将被转换成字符串。例如:int age=13;String rating=PG+age;将把rating的值赋为字符串“PG13”。这种特性常被用在输出语句中,例如:System.out.println(The answer is+answer);,3.String对象的编辑,字符串在Java 中以String 类的一个实例存在,所以每个字符串对象本身会拥有几个可操作的方法。常用的方法下表所示。,【示例4-7】:StringDemo.java,public class StringDemo public static void main(String args)String text=hello;System.out.println(字符串内容:+text);System.out.println(字符串长度:+text.length();System.out.println(等于hello?+text.equals(hello);System.out.println(转为大写:+text.toUpperCase();System.out.println(转为小写:+text.toLowerCase();,程序运行结果:字符串内容:hello字符串长度:5等于hello?true转为大写:HELLO转为小写:hello,4.String对象的访问,【示例4-7】:StringDemo.java,【示例4-8】CharAtString.javapublic class CharAtString public static void main(String args)String text=Ones left brain has nothing right.n+Ones right brain has nothing left.n;System.out.println(字符串内容:);for(int i=0;i text.length();i+)System.out.print(text.charAt(i);System.out.println(n 第一个left:+text.indexOf(left);System.out.println(最后一个left:+text.lastIndexOf(left);char charArr=text.toCharArray();System.out.println(n 字符Array 内容:);for(int i=0;i charArr.length;i+)System.out.print(charArri);,程序运行结果:字符串内容:Ones left brain has nothing right.Ones right brain has nothing left.第一个left:6最后一个left:66 字符Array 内容:Ones left brain has nothing right.Ones right brain has nothing left.,5.判断String对象是否相等,1)equals方法:要测试两个字符串是否相等,可以使用equals方法。如果字符串p和t相等,那么表达式:p.equals(t)的返回值为true,否则返回值为false。注意p和t可以是字符串变量,也可以是字符串常量。例如:表达式“Hello”.equals(t)就是合法的。要判断两个字符串除了大小写区别之外是否相等,可以使用equalsIgnoreCase方法。如:“Hello”.equalsIgnoreCase(“hello”)的返回值为true。2)=“=”用来判断两个引用变量是否指向同一位置。不要使用“=”操作符来判断两个字符串是否相等,它只能判断两个串是否指向同一个引用。,【例4-9】EqualsDemo.java,public class EqualsDemo public static void main(String args)String s1=aaaa;String s2=new String(aaaa);String s3=aaaa;String s4=new String(aaaa);System.out.println(s1=s3);/字符串常量引用同一常量池中的对象 System.out.println(s2=s4);/字符串对象将分别创建 System.out.println(s1.equals(s2);System.out.println(s3.equals(s4);,程序运行结果:truefalsetruetrue,4.2.2 StringBuffer类,StringBuffer 类(字符串缓冲器类),表示了可变长度的可写的字符序列。与String类不同,StringBuffer类是一个在操作中可以更改其内容的字符串类,即一旦创建了StringBuffer类的对象,那么在操作中便可以更改和变动字符串的内容。也就是说,对于StringBuffer类对象,不仅能够进行查找和比较等操作,还可以进行添加、插入、修改之类的操作。每个StringBuffer对象都有一个容量,只要其字符序列的长度不超过其容量,就无需分配新的内部缓冲数组,如果内部缓冲数组溢出,StringBuffer对象的容量将自动增大。,4.2.2 StringBuffer类,StringBuffer 类(字符串缓冲器类),表示了可变长度的可写的字符序列。与String类不同,StringBuffer类是一个在操作中可以更改其内容的字符串类,即一旦创建了StringBuffer类的对象,那么在操作中便可以更改和变动字符串的内容。也就是说,对于StringBuffer类对象,不仅能够进行查找和比较等操作,还可以进行添加、插入、修改之类的操作。每个StringBuffer对象都有一个容量,只要其字符序列的长度不超过其容量,就无需分配新的内部缓冲数组,如果内部缓冲数组溢出,StringBuffer对象的容量将自动增大。,4.2.2 StringBuffer类,1.构造方法(1)public stringBuffer():默认构造方法。(2)public StringBuffer(int length):按照length作为初始容量初始化StringBuffer对象(3)Public StringBuffer(String Str):按照String对象str为StringBuffer对象中的初始字符串。,4.2.2 StringBuffer类,2.主要成员方法(1)Public int length():得到当前StringBuffer的长度(字符数)。(2)public int capacity():得到当前StringBuffer的容量。(3)public Synchronized void ensureCapacity(int minimumCapacity):确保StringBuffe的容量不小于minimumCapacity。(4)public synchronized void setLength(int newLength):设置StringBuffer的长度为newLength。(5)public synchronized char charAt(int index):得到指定位置index的字符。(6)public synchronized void getChars(int srcBegin,int srcEnd,char dst,int dstBegin):将StringBuffer中从srcBegin到srecEnd的字符拷贝到数组dst(开始位置为dstBegin)中。,【示例4-10】StringBufferDemo.java,public class StringBufferDemo StringBuffer sb1=new StringBuffer(Hello world!);StringBuffer sb2;StringBuffer sb3=new StringBuffer(10);public StringBufferDemo()sb2=new StringBuffer(This is Java code.);sb3=new StringBuffer(Hello Java code);String output=sb1:+sb1.toString()+nlength=+sb1.length()+ncapacity=+sb1.capacity();sb1.replace(4,6,);/将起始位置4和结束位置6中间的内容替换成“,”(包含4不包含6)sb1.setLength(30);/设置sb1的长度30 System.out.println(After add sb1s length,);/输出sb1的长度12 System.out.println(sb1s capacity is:+sb1.length();/sb1的容积范围是30 sb1.ensureCapacity(60);/使用StringBuffer类的方法ensureCapacity(),来设置可变字符串的最大存储容量 System.out.println(Set sb1s capacity,);System.out.println(Now sb1s capacity is:+sb1.capacity();System.out.println();System.out.println(sb2:+sb2.toString();/返回对象本身 System.out.println(Char at 0 in sb2 is:+sb2.charAt(0);/返回字符串第i个位置的字符 System.out.println(Char at 9 in sb2 is:+sb2.charAt(9);char ch=new charsb2.length();,【示例4-10】StringBufferDemo.java,char ch=new charsb2.length();sb2.getChars(8,12,ch,0);System.out.println(The char from 8 to 12 is:);/getChars(int srcBegin,int srcEnd,char dst,int dstBegin)/将字符从此序列复制到目标字符数组 dst。for(int i=0;i4;i+)System.out.print(+chi+,);System.out.println(n);System.out.println(sb3:+sb3.toString();System.out.println(After append string to sb3,);System.out.println(world.StringBufferDemo!);System.out.println(New sb3:n+sb3.toString();System.out.println(After set the 5th char,);sb3.setCharAt(10,!);System.out.println(the new sb3:n+sb3.toString();public static void main(String args)StringBufferDemo stringBufferDemo=new StringBufferDemo();,4.2.3比较String类与StringBuffer类,1相同点String类和StringBuffer类有以下的相同点:(1)String类和StringBuffer类都用来处理字符串。(2)String类和StringBuffer类都提供了length()、toString()、charAt()和subString()方法,它们的用法在两个类中相同。(3)对于String类和StringBuffer类,字符在字符串中的索引位置都从0开始。(4)两个类中的substring(int begingIndex,int endIndex)方法都用来截取子字符串,而且截取的范围都从beginIndex开始,一直到endIndex-1为止,截取的字符个数为endIndex-beingIndex。,4.2.3比较String类与StringBuffer类,2不同点String类和StringBuffer类有以下的不同点。(1)String类是不可变类,而StringBuffer类是可变类。String对象创建后,它的内容无法改变。String类的substring()、concat()、toLowerCase()、toUpperCase()和trim()等方法都不会改变字符串本身,而是创建并返回一个包含改变后内容的新字符串对象。而StringBuffer的append()、replaceAll()、replaceFirst()、insert()和setCharAt()等方法都会改变字符缓冲区中的字符串内容。(2)String类覆盖了Object类的equals()方法,而StringBuffer类没有覆盖Object类的equals()方法。(3)两个类都覆盖了Object类的toString()方法,但各自的实现方式不一样:String类的toString()方法返回了当前String实例本身的引用,而StringBuffer类的toString()方法返回一个以当前StringBuffer的缓冲区中的所有字符为内容的新String对象的引用。(4)String类对象可以用操作符“+”进行连接,而StringBuffer类对象之间不能通过操作符“+”进行连接。,