第 3章 字符串和数组本章介绍 Java处理字符串和数组。字符串由一系列字符组成,这些字符可视为一个单元。本章将详细讨论
java.lang包中的 String类,StringBuffer类和 java.util
包中 StringTokenizer类的功能。数组是相同类型的相关数据项组成的数据结构,本章主要讨论一维数组和多维数组的使用。
3.1字符串字符串是字符的序列,它是组织字符的基本数据结构,
从某种程度上来说有些类似于字符的数组。在 Java中,字符串被当作对象来处理。程序中需要用到的字符串可以分为两大类,一类是创建之后不会再做修改和变动的 字符串常量 ;另一类是创建之后允许再做更改和变化的 字符串变量 。对于字符串常量,由于程序中经常需要对它做比较,
搜索之类的操作,所以通常把它放在一个具有一定名称的对象之中,由程序对该对象完成上述操作。
java语言所提供的 3种常用字符串类:
String类(字符串类);
StringBuffer类(字符串缓冲器);
StringTokenizer类(词法分析器类)。
3.1字符串 —— String:构造
构造一个字符串字符串常量是用双引号括住的一串字符。如
,welcome to java!,。要创建一个字符串,需要用到下面的语法:
String 字符串变量名 = new String (字符串常量 );
另外 java还提供了一个简单的创建字符串的简单语法:
String 字符串变量名 = 字符串常量。
1,length
public int length( )
此方法返回字符串的字符个数,如:
String s = "abc";
System.out.println( s.length( ) );
则将显示字符个数为 3。
3.1字符串 —— String:基本方法
2,charAt
public char charAt (int index )
该方法返回字符串中 index位置上的字符,其中 index值的范围是 0~ length-1。
3,getChars
如果要从字符串中提取一个以上的字符,则可以用此方法:
public void getchars (int srcbegin,int end,char buf[],int
dstbegin)
其中,srcbegin为要提取的第一个字符在源串中的位置,
end为要提取的最后一个字符在源串中的位置,字符数组 buf[]
存放目的字符串,dstbegin为提取的字符串在目的串中的起始位置。
3.1字符串 —— String:基本方法
4.比较两个字符串是否相等的方法:
public boolean equals ( Object anObject)
5.比较两个字符串在不区分大小写时是否相等的方法:
public boolean equals IgnoreCase( Object anObject)
6.比较两个字符串大小的方法:
public int compareTo ( Object anObject)
如,s1.compareTo ( s2)
如果 s1等于 s2,方法返回 0;如果按字典顺序 s1小于 s2,方法返回一个小于 0的值;如果按字典顺序 s1大于 s2,方法返回一个大于 0的值。
7.检查在指定范围内是否有指定前缀内容的方法:
public boolean startsWith (String pre,int toffset)
3.1字符串 —— String:基本方法
8.连接两个字符串的方法:
public String concat ( String str)
如:,Hello,,,concat (,java”),concat (,World!”)
返回,Hello,java World!”。
9.返回指定字符和指定字符串在字符串中第一次出现的位置值的方法:
public int indexOf (char ch)
public int indexOf ( String str )
10.在字符串中使用指定字符进行替换的方法:
public String replace ( char oldchar,char newChar )
11.取子串的方法:
public String substring (int start,int end)
12.把字符串中字符转换为大小写的方法:
public String toUpperCase ( )
public String toLowerCase ( )
3.1字符串 —— String:基本方法
public class StringDemo2
{ public static void main(String args[])
{ String strOb1 = "First String";
String strOb2 = "Second String";
String strOb3 = strOb1;
System.out.println("Length of strOb1," +strOb1.length());
System.out.println("Char at index 3 in strOb1," +strOb1.charAt(3));
if(strOb1.equals(strOb2))
System.out.println("strOb1 = = strOb2");
else
System.out.println("strOb1 != strOb2");
if(strOb1.equals (strOb3))
System.out.println("strOb1 == strOb3");
else
System.out.println("strOb1 != strOb3");
}
}
3.1字符串 —— String:示例运行结果为:
Length of strOb1,12Char at index 3 in strOb1,s
strOb1 != strOb2strOb1 == strOb3
3.1字符串 —— String:示例字符串一旦创建,它的值就固定了,但在实际应用中,经常需要对字符串的内容做动态修改,Java类的替代品 StringBuffer类(字符串缓冲器类型)可以实现该操作。 StringBuffer类比 String类更灵活,可以在字符串缓冲区中添加、插入、追加新内容。
1.构造一个字符缓冲区
public StringBuffer( )
建立一个空串的缓冲区,长度为 16。
StringBuffer ( int length)
建立一个长度为 length的空串缓冲区。
StringBuffer ( String str)
初始化缓冲区内容为给定的字符串 str,并提供另 16个字符的空间供再次分配。 类似于 Vector
3.1字符串 —— StringBuffer:创建
1.获得字符串长度的方法:
public int length ( )
2.重新设置字符串长度的方法:
public void setLength (int newLength )
3.返回当前缓冲区容量的方法
public int capacity ( )
4.在字符串添加新内容的方法:
public StringBuffer append (String str)
5.删除字符串指定内容的方法:
public StringBuffer delet (int start,int end)
6.使用字符串替换指定内容的方法:
public StringBuffer replace (int start,int end,String str)
7.在指定位置插入字符串的方法:
public StringBuffer insert (int offset,String str)
8.反转字符串内容的方法:
public StringBuffer reverse ( );
3.1字符串 —— StringBuffer:基本方法例子 3.2
3.1.3 StringTokenizer类
当我们分析一个字符串并将字符串分解成可被独立使用的单词时,可以使用 java.util包中的 StringTokenizer
类,该类有两个常用的构造方法:
StringTokenizer( String s) 为字符串 s构造一个分析器。
使用默认的分隔符集合,即空格符(若干个空格被看做一个空格)、换行符、回车符,Tab符、进纸符。
StringTokenizer(String s,String dilim) 为字符串 s构造一个分析器。参数 dilim中的字符被作为分隔符。
我们把一个 StringTokenizer对象称作一个字符串分析器。
一个分析器可以使用 nextToken()方法逐个获取字符串中的语言符号(单词),每当调用 nextToken()时,都将在字符串中获得下一个语言符号,每当获取到一个语言符号,字符串分析器中的负责计数的变量的值就自动减一,
该计数变量的初始值等于字符串中的单词数目。
常用 while循环逐个获取语言符号,用 hasMoreTokens()控制循环。
StringTokenizer st = new StringTokenizer("this is a test");
while (st.hasMoreTokens())
{
System.out.println(st.nextToken());
}
输出结果为:
this
is
a
test
3.1字符串 —— StringTokenizer
3.2数组当我们需要存储一组数据时,由于为每一个数据声明一个变量来存放是不可能的。因此,我们需要一个更高效组织数据的方法,这就是将要介绍的数组。数组是一种最简单的复合数据类型,是多个相同数据类型数据的组合,它的出现实现了对这些相同数据的统一管理。 Java将数组作为对象处理,有一维数组和多维数组之分。
3.2数组 —— 一维数组:定义一维数组的声明方式为:
type[ ] arrayName;
其中类型 (type)可以为 Java中任意的数据类型,包括简单类型和组合类型,数组名 arrayName为一个合法的标识符,[ ]指明该变量是一个数组类型变量。
例如:
int[ ] intArray;
声明了一个整型数组,数组中的每个元素为整型数据。
与 C,C++不同,Java在数组的声明中并不为数组元素分配内存,因此 [ ]中不用指出数组中元素的个数,即数组长度,
而且对于如上声明一个数组是不能访问它的任何元素的。
必须经过初始化或分配内存后,才能应用数组的元素。
3.2数组 —— 一维数组:定义一维数组定义之后,必须经过初始化才可以引用。数组的初始化分为静态初始化和动态初始化两种:
静态初始化,在定义数组的同时对数组元素进行初始化,例如:
int[] intArray={1,2,3,4};//定义了一个含有 4个
// 元素的 int型数组。
3.2数组 —— 一维数组:初始化动态初始化,使用运算符 new为数组分配空间,对于简单类型的数组,其格式如下:
type[] arrayName=new type[arraySize];
3.2数组 —— 一维数组:初始化例如:
String[] stringArrar; //定义一个 String类型的数组
stringArray = new String[3]; //给数组 stringArray分配 3个应用
//空间,初始化每个引用值为 null
stringArray[0]=new String(“how”);
stringArray[1]=new String(“are”);
stringArray[2]=new String(“you”);
初始化各数组元素
3.2数组 —— 一维数组:初始化当声明了一个数组,并用运算符 new为它分配了内存空间后,就可以引用数组中的每一个元素了。元素的引用方式为:
arrayName[index]
index为数组下标,可以是整型常数或表达式,如:
arrayName[1],arrayName[i],arrayName[6*i]等。下标是 0序的,即从 0开始,一直到数组长度减 1。
3.2数组 —— 一维数组,引用另外,与 C,C++中不同,Java对数组元素要进行越界检查以保证安全性。同时,对于每个数组都有一个属性 length指明它的长度,例如:
intArray.length指明数组 intArray的长度。
3.2数组 —— 一维数组,边界检查
public class IntArray
{
public static void main(String args[ ])
{
int a[ ]={1,2,3};
int i,sum=0;
for(i=0;i<a.length;i++)
sum=sum+a[i];
for(i=0;i<a.length;i++)
System.out.println(" a[" +i+"]="+a[i]);
System.out.println(" sum="+sum);
}
}
声明一个整型数组并对它初始化,在屏幕上输出各元素的值和其总和。
3.2数组 —— 一维数组,示例运行结果为:
a[0] =1
a[1] =2
a[2] =3
sum =6
3.2数组 —— 一维数组:示例
public class BubbleSort
{ public static void main(String args[ ])
{ int i,j;
int intArray[]={301,-9,70,25};
int len=intArray.length;//输出排序前的数组
for( i=0;i<len;i++)
System.out.print(intArray[i]+ " ");
System.out.println();//排序
for( i=0;i<len-1;i++)
for( j=i+1;j<len;j++)
if(intArray[i]>intArray[j])
{ int t=intArray[i];
intArray[i]=intArray[j];
intArray[j]=t;
}//输出排序后的数组
for( i=0;i<len;i++)
System.out.print(intArray[i]+ " ");
}}
用冒泡法,对已有数据从小到大排序。
3.2数组 —— 一维数组,示例运行结果为:
301 -9 70 25
-9 25 70 301
3.2数组 —— 一维数组:示例
在 java中,每个数组都有一个属性 length指明它的长度
(即该数组可以容纳元素的个数),
如,intArray.length指明数组 intArray的长度。
java运行时系统时,会对数组下标进行越界检查,因此下标值必须在指定的范围内,0~intArray.length。,数组的最大下标值为 length-1,以保证安全性;如有越界将产生下标越界( ArrayIndexOutOfBoundexception)的编译错误。
另外 java中的数组一旦创建,大小就不可以改变了。但是,可以为数组重新分配空间,这样原来数组元素的值将被清除。它还是独立的类,有自身的方法和属性。
3.2数组 —— 一维数组:数组的长度
在 java中,在两个数组间使用赋值语句( =),
例如,newArray = array;
这两个数组名指向的都是同一数组,改变 newArray数组元素的值,array数组元素的值也会随之改变。因为数组名存放的是一个引用地址(为数组分配的存储空间的首地址),是一个地址常量。如果把数组名赋值给另一个数组名时,传送的是地址,这样两个数组名指向同一个地址,
实际上是给同一个数组取两个名字。如果改变其中一个数组的内容,另一个也会改变。
3.2数组 —— 一维数组:数组的复制
OxAB
12
16
newArray
OxDD
6
18
array OxDD
6
18
newArray
OxDD
array
12
16
如果希望复制一个数组,实现数组和被复制的数组分别占用独立的内存空间,则有下面三种方法:
1.用循环语句复制数组的每个元素如,for (int i-0 ; i < intArray,length ; i++ )
targetArray [ i ] = intArray [ i ] ;
2.使用 Object类的 clone方法如,int [ ] targetArray = ( int [ ] ) intArray,clone ( ) ;
3.使用 System类中的静态方法 arrycopy:
System,arraycopy ( sourceArray,offset1,targetArray,offset2,
number )
其中,sourceArray和 targetArray是源数组和目标数组名,它们必须是已经初始化的数组。 Offset1和 offset2分别是源数组和目标数组操作的起始下标,number表示要复制的元素的个数。
例子 ArrayCopy
3.2数组 —— 一维数组:数组的复制如果需要表示更复杂的数据,比如矩阵或表格,
就需要二维数组。在任何语言中,多维数组都被看作数组的数组。比如二维数组是一个特殊的一维数组,其每一个元素又是一个一维数组。
我们主要以二维数组为例来说明,高维数组与此类似。
3.2数组 —— 多维数组二维数组的声明方式
type[ ][ ] arrayName;
例如:
int[ ][ ] intArray;
与一维数组一样,这时对数组元素也没有分配内存空间,同样要使用运算符 new来分配内存或直接初始化,然后才可以访问每个元素。
3.2数组 —— 二维数组:定义二维数组的初始化也分为静态和动态两种。
静态初始化,在定义数组的同时为数组分配空间。
int[][] intArray={{1,2},{2,3},{3,4}};
不必指出数组每一维的大小,系统会根据初始化时给出的初始值的个数自动算出数组每一维的大小。
3.2数组 —— 二维数组:初始化动态初始化,对高维数组来说,分配内存空间有下面两种方法:
1.直接为每一维分配空间,如:
type[][] arrayName=new type[arraylength1][arraylength2]
例如:
int[][] a=new int[2][3];
3.2数组 —— 二维数组:初始化
2.从最高维开始(而且必须从最高维开始),分别为每一维分配空间,如:
String s[ ][ ]=new String[2][ ];
s[0]=new String[2];
s[1]=new String[3];
s[0][0]=new String(“Good”);
s[0][1]=new String(“Luck”);
s[1][0]=new String(“to”);
s[1][1]=new String(“you”);
s[1][2]=new String(“!”);
3.2数组 —— 二维数组:初始化二维数组的引用对二维数组中每个元素,引用方式为:
arrayName[index1][index2]
其中 index1和 index2为数组下标,为整型常数和表达式,都是 0序的。
二维数组举例 — 例子 3.6
两个矩阵相乘,参照参考书在课余时间上机练习。
3.2数组 —— 二维数组:引用及示例