第四章 数组与字符串

62
第第第 第第第第第第 第第第第第第 第第第第第 第第第 [email protected] http://211.155.231.249:8009

Upload: elmo-barnett

Post on 30-Dec-2015

96 views

Category:

Documents


11 download

DESCRIPTION

第四章 数组与字符串. 浙江工业大学 计算机学院 赵小敏 [email protected] http://211.155.231.249:8009. 主要内容. 数组 数组的应用 字符串 String 可变字符序列 StringBuffer 可变字符序列 StringBuilder. 4.1 数组. 数组是相同类型的数据元素按顺序组成的一种复合数据类型,元素在数组中的相对位置由下标来指明。 例如 :public static void main(String args []) 其中 args 是 String 类型的数组 占用连续的内存地址 数组的静态性 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第四章 数组与字符串

第四章 数组与字符串

浙江工业大学 计算机学院赵小敏[email protected]://211.155.231.249:8009

Page 2: 第四章 数组与字符串

主要内容 数组 数组的应用 字符串 String 可变字符序列 StringBuffer 可变字符序列 StringBuilder

Page 3: 第四章 数组与字符串

4.1 数组

数组是相同类型的数据元素按顺序组成的一种复合数据类型,元素在数组中的相对位置由下标来指明。

例如 :public static void main(String args[])其中 args 是 String 类型的数组

占用连续的内存地址 数组的静态性

一旦创建就不能修改数组的长度

Page 4: 第四章 数组与字符串

数组声明

一维数组变量的声明格式有如下两种 :(1) 数组元素的数据类型 [ ] 变量名 ;

(2) 数组元素的数据类型 变量名 [ ]; 示例 :

int [ ] c;

String[ ] names;

int c[ ];

String names[ ];

Page 5: 第四章 数组与字符串

数组的实例化

Java 数组实际上也是对象,所以可通过 new 关键字来创建。

示例 : int[ ] c; // 声明 , 不必指定数组的大小 c = new int[12]; // 创建对象,并分配内存 上面的两个语句可以简化成一个语句 : int[ ] c = new int[12];

数组的长度用数组名 .length ,如 c.length 数组元素用数组名 [ 下表 ] 表示,下标的范围是 0 ~

数组长度- 1 ,如 c[0]

Page 6: 第四章 数组与字符串

初始化数组

基本数据类型的元素初始化为 0 值或 false 非基本数据类型的元素初始化为 null 可以采用循环结构初始化数组 示例 :

double[ ] squares; squares = new double[100]; for (int i=0; i < squares.length; i++){ squares[i] = i*i; }

Page 7: 第四章 数组与字符串

通过初始化语句创建数组

Java 语言允许通过数组的初始化语句创建数组 示例 :

int[ ] n = { 10, 20, 30, 40, 50 }; 上面语句创建了一个含有五个元素的数组 下标值分别为 0, 1, 2, 3, 4

这时不需要运算符 new

Page 8: 第四章 数组与字符串

数组的内存分配示例

Page 9: 第四章 数组与字符串

数组的注意事项

当通过循环遍历数组时 下标永远不要低于 0 下标永远要比数组元素个数小

当数组下标出错, Java 产生 ArrayIndexOutOfBoundsException 异常

数组一旦创建后,不能调整大小 可使用相同的引用变量来引用一个全新的数组 int []a = new int[6];

a = new int[10];

Page 10: 第四章 数组与字符串

多维数组

最常用的多维数组是二维数组 int[ ][ ] a = new int[3][4];

二维数组可以理解成如下图示的表格a[ 0 ][ 0 ]

a[ 1 ][ 0 ]

a[ 2 ][ 0 ]

a[ 0 ][ 1 ]

a[ 1 ][ 1 ]

a[ 2 ][ 1 ]

a[ 0 ][ 2 ]

a[ 1 ][ 2 ]

a[ 2 ][ 2 ]

a[ 0 ][ 3 ]

a[ 1 ][ 3 ]

a[ 2 ][ 3 ]

行的下标值列的下标值

Page 11: 第四章 数组与字符串

二维数组的创建(内存分配)

(1) 直接为每一维分配空间,如: int a[ ][ ] = new int[2][3]; 该语句创建了一个二维数组 a ,其较高一维含两

个元素,每个元素为由 3 个整型数构成的整型数组。

此时该数组的元素为: a[0][0] a[0][1] a[0][2]

a[1][0] a[1][1] a[1][2]

Page 12: 第四章 数组与字符串

二维数组的创建(内存分配)

(2) 从最高维开始,分别为每一维分配空间 二维数组的实际上是数组的数组,即创建以数组

为元素的数组,意味着 : 二维数组的每一行可以具有不同的列数,如:

int b[ ][ ] = new int[2][ ]; // 最高维含 2 个元素,每个元素为一个整型数组

b[0] = new int[3]; b[1] = new int[5]; 此时该数组的元素为:b[0][0] b[0][1] b[0][2]b[1][0] b[1][1] b[1][2] b[1][3] b[1][4]

Page 13: 第四章 数组与字符串

二维数组元素的初始化

(1) 先创建二维数组,然后通过循环直接对每个元素进行赋值,如:

int[ ][ ] matrix = new int[4][5];

for (int row=0; row < matrix.length; row++){ for (int col=0; col < matrix[row].length; col++){ matrix[row][col] = row + col; } }注:二维数组的长度指的是二维数组的行数,用数组

名 .length 表示,某 i 行的数组长度(该行的列数)用数组名 [i].length 表示

Page 14: 第四章 数组与字符串

二维数组元素的初始化

(2) 在声明数组的同时进行初始化。如: int a[ ][ ]={{2,3},{1,5},{3,4}};

声明了一个 3×2 的数组,并对每个元素赋值,即: a[0][0] = 2 a[0][1] = 3

a[1][0] = 1 a[1][1] = 5

a[2][0] = 3 a[2][1] = 4

Page 15: 第四章 数组与字符串

例:构造杨辉三角形

1. class Yanghui{2. public static void main(String[] args){3. int yanghui[ ][ ]={{1},{1,1},{1,2,1},{1,3,3,1}, {1,4,6,4,1}};4. for(int i=0;i<yanghui.length;i++){5. for(int j=0;j<yanghui[i].length;j++){6. System.out.print("\t"+yanghui[i][j]);7. }8. System.out.println();9. }10. }11. }

Page 16: 第四章 数组与字符串

4.2 数组的应用

复制数组 数组的封装类 Arrays 数组用作参数和返回值 main 方法的数组参数获取命令行输入

Page 17: 第四章 数组与字符串

复制数组 Java 在 System 类中提供了一个特殊的方法

arraycopy() ,用于实现数组之间的复制1. public class ArrayCopy{2. public static void main(String args[]){ 3. int i;4. int arr1[]={1,2,3,4,5,6,7,8,9,10};5. int arr2[]=new int[10];

6. // 把 arr1 中所有元素复制到 arr2 中,下标从 0 开始7. System.arraycopy(arr1,0,arr2,0,arr1.length); 8. for(i=0;i<arr2.length;i++)9. System.out.print(arr2[i]+" ");10. System.out.println();11. }12. }

Page 18: 第四章 数组与字符串

数组的封装类 Arrays

java.util 包封装了一个 Arrays 类,可实现数组操作的查找、复制和排序

binarySearch(int[] a, int fromIndex, int toIndex, int key) copyOf(int[] original, int newLength) copyOfRange(int[] original, int from, int to) sort(int[] a)

Page 19: 第四章 数组与字符串

例 :数组元素排序

1. import java.util.Arrays;2. public class ArraySort {3. public static void main(String []args){4. int []hold={10,1,8,3,6,5,4,7,2,9};5. Arrays.sort(hold);6. for(int i=0;i<hold.length;i++){7. System.out.print(hold[i]+" ");8. }9. }10. }

Page 20: 第四章 数组与字符串

数组用作参数和返回值

数组可以作为参数传递给方法,也可以作为方法的返回值

在调用的方法中的数组对象与调用者中的是同一个。

如果在方法中修改了任何一个数组元素,因为这个数组与方法之外的数组对象是同一个,所以方法之外的数组也将发生改变。

Page 21: 第四章 数组与字符串

例 :数组作为调用方法的传递参数

1. public class CallArray{2. static void updateArray (int[ ] arrays){3. arrays[3]=10;4. }5. public static void main(String []args){6. int [ ]hold={0,1,2,3,4,5,6,7,8,9};7. updateArray(hold);8. for(int i=0;i<hold.length;i++){9. System.out.print(hold[i]+" ");10. } 11. }12. }

运行时, hold 数组的内容如下 : 0,1,2,10,4,5,6,7,8,9

Page 22: 第四章 数组与字符串

例:数组作为方法的返回结果

1. public class ReturnArray{2. static int[ ] updateArray(int[] arrays){3. for(int i=0;i<arrays.length;i++){4. arrays[i]=i;5. }6. return arrays;7. }8. public static void main(String []args){9. int [ ]hold={9,8,7,3,5,6,4,2,1,0};10. hold= updateArray(hold);11. for(int i=0;i<hold.length;i++){12. System.out.println("hold["+i+"]="+hold[i]);13. } 14. }15. }

Page 23: 第四章 数组与字符串

main 方法的数组参数获取命令行输入 在 Java 程序的主方法 public static void main

(String args[ ]) 中, args[ ] 是一个字符串数组,用来接收应用程序被调用时由用户直接从键盘输的参数。

例:应用程序被调用时参数的传递public class MyFriend{ public static void main (String arg[]){ System.out.println(arg[0]+ "and"+ arg[1] +"are my good friends! "); }}

程序经编译后,采用命令 java MyFriend Tom Alice 来执行 程序运行结果为: Tom and Alice are my good friends!

Page 24: 第四章 数组与字符串

4.3 字符串 String

在 Java 中字符串是对象,用 String 类来创建 在 Java 中对字符串的处理,需要事先创建一个

String 的实例,即像其它对象一样,需要对String 声明和实例化, 如:

String name;

name = new String( “Latte” );

但我们也可以用简写的形式,像基本数据类型一样创建 String ,如:String name;

name = “Latte”;

Page 25: 第四章 数组与字符串

String 对象

与 C 语言不同 : 字符 (char) 数组不是字符串(String) , String 数值不必以 '\u0000' 结束

String 对象一旦被创建后就不能被改变,称为非可变对象

Page 26: 第四章 数组与字符串

String 的构造方法

1. String() 2. String(byte[] bytes) 3. String(byte[] bytes, Charset charset) 4. String(byte[] bytes, int offset, int length) 5. String(byte[] bytes, int offset, int length, Charset charset) 6. String(byte[] bytes, int offset, int length, String charsetName) 7. String(byte[] bytes, String charsetName) 8. String(char[] value) 9. String(char[] value, int offset, int count) 10. String(int[] codePoints, int offset, int count) 11. String(String original) 12. String(StringBuffer buffer) 13. String(StringBuilder builder)

Page 27: 第四章 数组与字符串

String 对象的创建

String s1=“hello”;String s2=“hello”;

String s3=new String(“hello”);String s4=new String(“hello”);

Page 28: 第四章 数组与字符串

String 对象的内存分配

String s1=“hello”;String s2=“hello”; John

Java

World

堆内存

字符串池

JVM

Tom

String

s1hellohello

s2

Page 29: 第四章 数组与字符串

String 对象的内存分配 ( 续 )

String s3=new String(“hello”);String s4=new String(“hello”); John

Java

World

堆内存

字符串池

hello

Tom

String

JVM

hello

String

s3

hello

String

s4

s1s2

Page 30: 第四章 数组与字符串

String 对象的内存分配 ( 续 )

s1=s1+“ world”;John

Java

World

堆内存

字符串池

hello

Tom

String

JVM

hello

String

s3

hello

String

s4

hello world

String

s1

s1s2

Page 31: 第四章 数组与字符串

String 类的方法及应用

字符串长度 比较字符串 连接字符串 拷贝字符串 搜索字符 搜索子串 修改字符串 其他方法

Page 32: 第四章 数组与字符串

字符串长度 方法 length( )

返回 String 的长度 与数组不同之处 : String 不含有 length 成员变量

String name = “Sumatra”,str1 = “one”,str2 = “”,str3;

对 str3 来说,没有创建对象,内容为null. 所以无法确定其长度

对 str3 来说,没有创建对象,内容为null. 所以无法确定其长度

name.length( );

str1.length( );

str2.length( );

str3.length( );

7

3

0

编译错误

Page 33: 第四章 数组与字符串

比较字符串

字符类型的数据也是数值类型数据 比较字符串大小,实际上就是依次比较其所包含的字

符的数值大小 小写字母与大小字母是不相同的 方法有: equals() equalsIgnoreCase() regionMatches() compareTo() compareToIgnoreCase()

Page 34: 第四章 数组与字符串

equals() 方法 boolean equals(Object anObject)

比较当前的字符串与指定的对象 比较结果为真当且仅当给定的参数不为空,

并且具有完全相同的字符序列

Page 35: 第四章 数组与字符串

应用 1 : String 对象的比较String s1=“hello”;String s2=“hello”;String s3=new String(“hello”);

s1==s2s1==s3s1.equals(s2);s1.equals(s3);

truefalsetruetrue

(1)

(2)

方式 (1) 比方式 (2)效率高

“==” 比较地址 "equals" 比较内容

Page 36: 第四章 数组与字符串

equalsIgnoreCase() 方法

boolean equalsIgnoreCase(String anotherString) 判别相等,但不区分大小写 例如 : 在不区分大小写情况下 ,

“hello” 与“ HELLO” 相等

Page 37: 第四章 数组与字符串

regionMatches() 方法

regionMatches() 方法实现子串匹配相等的比较,返回值为 boolean 类型。若相等则返回 true ,否则返回 false

格式如下: boolean str1. regionMatches(boolean

ignoreCase,int offset,String str2,int offset,int len) 参数说明:boolean ignoreCase 若为 true ,则忽略大小写int offset 确定 str1 的起始偏移量String str2 str2 为参与比较的另一个串int offset 确定 str2 的起始偏移量int len 确定子串长度

Page 38: 第四章 数组与字符串

compareTo() 与compareToIgnoreCase() int compareTo(String anotherString)

比较两个字符串的内容 返回 :

0 : 如果字符串内容完全相同 小于 0 的值 : 如果在比较第一个不相同字符,当前字符串

的字符的值小于 anotherString 对应的字符的值 大于 0 的值 : 如果在比较第一个不相同字符,当前字符串

的字符的值大于 anotherString 对应的字符的值 int compareToIgnoreCase(String str)

比较两个字符串的内容,但不区分大小写

Page 39: 第四章 数组与字符串

连接字符串

“+” 运算符 concat()

Page 40: 第四章 数组与字符串

拷贝字符串

copyValueOf() getChars() toCharArray() substring()

Page 41: 第四章 数组与字符串

搜索字符

charAt(int index) indexOf(int ch) indexOf(int ch,int fromIndex) lastIndexOf(int ch) lastIndexOf(int ch,int fromIndex)

Page 42: 第四章 数组与字符串

搜索子串

indexOf(String str) indexOf(String str, int fromIndex) lastIndexOf(String str) lastIndexOf(String str, int fromIndex)

返回第一次找到的时下标,如果没有找到,则返回 -1

Page 43: 第四章 数组与字符串

修改字符串

replace () toLowerCase() toUpperCase() trim ()

Page 44: 第四章 数组与字符串

String 的其他方法

valueOf() 将参数的值转化成相应的字符串 replace() 替换字符串中的字符或字串 toUpperCase() toLowerCase() toCharArray( ) 将字符串转换成字符数组 intern() 返回具有相同内容的字符串的引用

Page 45: 第四章 数组与字符串

4.4 可变字符序列StringBuffer StringBuffer 类创建的串可以修改,可

以对串的内容进行增、删、改操作。 StringBuffer()

           构造一个其中不带字符的字符串缓冲区,初始容量为 16 个字符。

StringBuffer(int capacity)            构造一个不带字符,但具有指定初始容量的字符串缓冲区。

StringBuffer(String str)            构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容

Page 46: 第四章 数组与字符串

StringBuffer 方法 public StringBuffer append(String str) public StringBuffer insert(int offset,String str) public StringBuffer delete(int start,int end) public StringBuffer deleteCharAt(int index) public StringBuffer replace(int start,int end,String

str) public void setCharAt(int index,char ch) public StringBuffer reverse( ) public int length( ) public int capacity( ) public void setLength(int newLength)

Page 47: 第四章 数组与字符串

StringBuffer 对象的内存分配StringBuffer sb=new StringBuffer();sb.append(“hello”);sb.append(“ world”);

堆内存

JVM

StringBuffer

sbhello

StringBuffer

sbhello world

StringBuffer

sb

初始容量为 16 个字符 长度为 0 容量为 16 个字符 长度为 5 容量为 16 个字符 长度为 11

Page 48: 第四章 数组与字符串

StringBuffer 对象的内存分配( 续 ) StringBuffer 内部实现是 char 数组,默认初始化长度为 16 ,每当字符串长度大于 char 数组长度时,JVM会构造更大的新数组,并将原先的数组内容复制到新数组

给 StringBuffer设置一个合理的初始化容量值 StringBuffer sb=new StringBuffer(1024);

新数组长度 ( 新容量 )=原容量 ×2+ 2

Page 49: 第四章 数组与字符串

编译后的字节码等同于以下源码:

应用:连接字符串操作 (1)

String s=“hello”;s=s+“ world”;

String s=“hello”; StringBuffer temp=new StringBuffer();temp.append(s);temp.append(“ world”);S=temp.toString();

运行期决定连接字符串

Page 50: 第四章 数组与字符串

运行期连接字符串操作

String s=“hello”;s=s+“ world”;

StringBuffer sb=new StringBuffer();sb.append(“hello”);sb.append(“ world”);

方式 (2) 比方式 (1)效率高

(1)

(2)

Page 51: 第四章 数组与字符串

编译后的字节码等同于以下源码:

应用:连接字符串操作 (2)

String s=“hello” +“ world”;

String s=“hello world”;

编译期决定连接字符串

Page 52: 第四章 数组与字符串

编译期连接字符串操作

StringBuffer sb=new StringBuffer();sb.append(“hello”);sb.append(“ world”);

方式 (1) 比方式 (2)效率高

(1)

(2)

String s=“hello” +“ world”;

Page 53: 第四章 数组与字符串

在编译期能确定字符串值时,采用 String s=“”; 形式来定义,使用“ +” 为字符串

连接的性能最佳

经常改变字符串的操作或在运行期才能确定字符串时,采用 StringBuffer

如何选用 String 和StringBuffer?

Page 54: 第四章 数组与字符串

尽量不要用 new 创建 String 对象 避免使用 “ =” 来重新构造 String 对象 在声明 StringBuffer 对象时,指定合适的容量,如

StringBuffer sb=new StringBuffer(1024);

使用 String 和 StringBuffer 注意事项

Page 55: 第四章 数组与字符串

可变字符序列 StringBuilder

StringBuilder 是 JDK1.5版本以后出来的 它是作为一个可变的字符序列。此类提供一个

与 StringBuffer 兼容的 API ,但不保证同步。 该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候

如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。

Page 56: 第四章 数组与字符串

思考 :编写程序测试以下三种代码方式的效率高低?

StringBuffer sb=new StringBuffer();for(int i=1;i<=5;i++) sb.append(String.valueOf(i));String s1=sb.toString()

(1)

(2)

String s=“1” +“2”+ “3”+ “4”+ “5”;

String s;for(int i=1;i<=5;i++) s+=String.valueOf(i);

(3)

Page 57: 第四章 数组与字符串

练习题

关于以下程序段,正确的说法是 1 . String  s1="Hello";

2 . String  s2="Hello";3 . if ( s1= =s2 )4 . System.out.println("s1= =s2");5 . if (s1.equals(s2))6 . System.out.println("s1.equals(s2) ");A.  行 4 与行 6 都将执行 B.  行 4 执行,行 6 不执行C.  行 6 执行,行 4 不执行D.  行 4 、行 6 都不执行

String  s2=new String("Hello");

答案 :A 修改后答案 :C

Page 58: 第四章 数组与字符串

练习题:阅读下面的程序,输出结果是什么?1. class TestString{2. public void stringReplace (String text) {3. text = text.replace('j' , 'i'); 4. text=text+"C";5. }6. public void bufferReplace (StringBuffer text) {7. text.setCharAt(0,'i');8. text = text.append("C"); 9. }10. public void change(char ch[]){11. ch[0]= 'Y';12. }13. public static void main(String args[]){14. String str1="java";15. StringBuffer str2=new StringBuffer("java");16. char ch[]={'j','a','v','a'}; 17. TestString t=new TestString(); 18. t.change(ch);19. t.stringReplace (str1); 20. t.bufferReplace (str2); 21. System.out.println(str1); 22. System.out.println(str2.toString()); 23. System.out.println (new String(ch)); 24. }25. }

输出结果:javaiavaCYava

Page 59: 第四章 数组与字符串

作业

4.1假设某班级有 20 个同学选修 Java 程序设计课程,请创建一个数组初始化所有同学的成绩,统计学生的平均成绩和各等级(优、良、中、及格和不及格)学生人数。

Page 60: 第四章 数组与字符串

作业4.2 、设有 3 个数组内容如下 :String x[]={"zero","one","two", "three",four",

"five","six",seven","eight","nine"} ;  String

y[]={ten","eleven","twelve","thirteen","fourteen","fifteen", "sixteen","seventeen","eighteen","nineteen" };

 String z[]={"twenty","thirty","fourty","fifty",  "sixty","seventy", "eighty","ninety"  };

用 Java 命令行输入一个小于 100 的整数,将其翻成英文表示。例如:输入 32 ,输出: thirty two        输入 14 ,输出: fourteen         输入 8 , 输出: eight    反之,输入英文表示 , 输出相应的整数

Page 61: 第四章 数组与字符串

作业

4.3 、设有一个由 20 个英文单词构成的字符串数组,要求:

( 1 )统计以字母 w 开头的单词数;( 2 )统计单词中含“ or” 字符串的单词数;( 3 )统计长度为 3 的单词数。

Page 62: 第四章 数组与字符串

Thank You… Any ??

Thank You… Any ??