⑥修改字符串
修改字符串的常用方法有:replace、toLowerCase、toUpperCase、trim。调用形式如下:
s1.replace(oldchar,newchar)--------用新字符newchar替代旧字符oldchar,若指定字符不存在,则不替代。
s1.toLowerCase( )--------将s1中的所有大写字母转换为小写字母。
s1.toUpperCase( )-------- 将s1中的所有小写字母转换为大写字母。
s1.trim( )--------删除s1中的首、尾空格。
【例7.7】修改字符串。
public class StrModify
{public static void main(Sring[] args)
{
String s1="Java";
s1=s1.replae('a', 'b');
System.out.println("s1=",+s1);
String s2=s1.toLowerCase( );
String s3=s1. toUpperCase ( );
System.out.println("s2=",+s2);
System.out.println("s3=",+s3);
s2= s1.trim( );
System.out.println("s2=",+s2);
}
}
运行结果:
C:/>java StrModify
s1= Jbvb
s2= jbvb
s3= JBVB
s2= jbvb
2.StringBuffer类
缓冲字符串类StringBuffer与String类相似,它具有String类的很多功能,甚至更丰富。它们主要的区别是StringBuffer对象可以方便地在缓冲区内被修改,如增加、替换字符或子串。与Vector对象一样,StringBuffer对象可以根据需要自动增长存储空间,故特别适合于处理可变字符串。当完成了缓冲字符串数据操作后,可以通过调用其方法StringBuffer.toString( )或String构造器把它们有效地转换回标准字符串格式。
(1)创建StringBuffer对象
可以使用StringBuffer类的构造器来创建StringBuffer对象。表6.4 是StringBuffer的构造器及其简要说明。
表6.4StringBuffer类构造器概要
构造器
说明
StringBuffer( )
构造一个空的缓冲字符串,其中没有字符,初始长度为16个字符的空间
StringBuffer(int length)
构造一个长度为length的空缓冲字符串
StringBuffer(String str)
构造一个缓冲字符串,其内容初始化为给定的字符串str,再加上16个字符的空间
【例7.8】用多种方法创建StringBuffer对象。
public class StrBufferSet
{public static void main(Sring[] args)
{
StringBuffers1=new StringBuffer( );
s1.append("Hello,Java!");
System.out.println("s1=" +s1);
StringBuffers2=new StringBuffer(10 );
S2.insert(0, "Hello,Java!");
System.out.println("s2="+s2);
StringBuffers3=new StringBuffer("Hello,Java!");
System.out.println("s3="+s3);
}
}
运行结果:
C:/>java StrBufferSet
s1=Hello,Java!
s2=Hello,Java!
s3=Hello,Java!
(2)StringBuffer类的常用方法
StringBuffer类是可变字符串,因此它的操作主要集中在对字符串的改变上。
①为StringBuffer的对象插入和追加字符串
可以在StringBuffer对象的字符串之中插入字符串,或在其之后追加字符串,经过扩充之后形成一个新的字符串,方法有:append和insert,调用形式如下:
s1.append(s2)--------将字符串s2加到s1之后。
s1.insert(int offset,s2)--------在s1从起始处offset开始插入字符串s2。
append和insert都有多个重载方法,这里不一一赘述。关于append和insert方法的使用见例6.8 。
②获取和设置StringBuffer对象的长度和容量
获取和设置StringBuffer对象的长度和容量的方法有:length、capacity、setlength,调用形式如下:
s1.length( )--------返回s1中字符个数。
s1. capacity ( )--------返回s1的容量,即内存空间数量。通常会大于length( )
s1. setlength (int newLength )--------改变s1中字符的个数,如果newLength大于原个数,则新添的字符都为空("");相反,字符串中的最后几个字符将被删除。
【例7.9】显示确定字符串的长度和容量,并改变字符串的长度。
public class StrLen
{public static void main(Sring[] args)
{
StringBuffers1=new StringBuffer("Hello,Java!");
System.out.println("The length is"+s1.length( ));
System.out.println("The allocated length is"+s1.capacity( ));
s1.setlength(100);
System.out.println("The new length is"+s1.length( ));
}
}
运行结果:
C:/>java StrLen
The length is11
The allocated length is22
The new length is100
③读取和改变StringBuffer对象中的字符
读取StringBuffer对象中的字符的方法有:charAt和getChar,这与String对象方法一样。在StringBuffer对象中,设置字符及子串的方法有:setCharAt、replace;删除字符及子串的方法有:delete、deleteCharAt。调用形式如下:
s1.setCharAt(int index,char ch)--------用ch替代s1中index位置上的字符。
s1.replace(int start,int end,s2)--------s1中从start(含)开始到end(不含)结束之间的字符串以s2代替。
s1.delete(int start,int end)--------删除s1中从start(含)开始到end(不含)结束之间的字符串。
s1.deleteCharAt(int index)------删除s1中index位置上的字符。
【例7.10】改变字符串的内容。
public class StrChange
{public static void main(Sring[] args)
{
StringBuffers1=new StringBuffer("Hallo,Java!");
s1.setCharAt(1, 'e');
System.out.println(s1);
s1.replace(1,5, "i");
System.out.println(s1);
s1.delete(0,3);
System.out.println(s1);
s1.deleteCharAt(4);
System.out.println(s1);
}
}
运行结果:
C:/>java StrChange
Hello,Java!
Hi,Java!
Java!
Java
7.2.2 System类
System类是一个特殊类,它是一个公共最终类,不能被继承,也不能被实例化,即不能创建System类的对象。
System类功能强大,与Runtime一起可以访问许多有用的系统功能。System类保存静态方法和变量的集合。标准的输入、输出和Java运行时的错误输出存储在变量in,out和err中。由System类定义的方法丰富并且实用。System类中所有的变量和方法都是静态的,使用时以System作为前缀,即形如“System.变量名”和“System.方法名”。
1.标准的输入输出
System类包含三个使用频繁的公共数据流,分别是:标准输入(in)、标准输出(out)、标准错误输出(err)。
① public static final InputStream in--------标准输入。
这个属性是InputStream类的一个对象,它是未经包装的原始Input Stream,读取System.in之前应该先加以包装。可以通过read()方法读取字节数据。
② public static final PrintStream out--------标准输出。
③ public static final PrintStream err---------标准输出。
out和err都已经被包装成PrintStream对象,所以可以直接使用System.out和System.err。可以通过方法print()、println()或write()方法很方便地完成各种数据类型的输出。out与err使用上的不同是: System.out用于输出普通信息,out的输出一般需要缓存;System.err一般情况下用来打印错误信息,不需要缓存,快速显示紧急信息。
关于InputStream类和PrintStream类将在java.io包中介绍。
2.System类的常用方法
System类有一些有用的方法,这些方法用于处理运行环境。下面简单介绍几个方法及其功能。
(1)获取当前时间
使用currentTineMillis( )可以记录程序执行的时间,这是一个特别有意义的用法。currentTineMillis( )方法返回自从1970年1月1日午夜起到现在的时间,时间单位是毫秒。如果要记录程序中一段有问题程序的运行时间,可以在这段程序开始之前调用currentTineMillis( )方法存储当前时间,在这段程序结束处再次调用currentTineMillis( )方法。执行该段程序所花费的时间为其结束时刻的时间值减去其开始时刻的时间值。下面的程序段可以用来估计一下执行某个循环所占用的时间:
long startTime=System.currenTimerMillis( );//记录循环开始时间
int sum=0;
for(int i=0;i<100000;i++){
sum+=i;
}
long endTime=System.currentTimeMillis( );// 记录循环结束时间
System.out.Println("time: "+(endTime-startTime)+ "milliseconds. ");
注意:虽然使用cuttentTimeMillis()方法可以计算出当前的日期和时间,但是获取当前日期和时间最好使用java.util中的Date类。
(2)快速复制数组
使用arraycopy()方法可以将一个任意类型的数组快速地从一个地方复制到另一个地方。这比使用循环编写的程序要快得多。调用形式为:
System.arraycopy(a1,int sourceStart,a2,int targetStart,int size)------将数组a1从下标sourceStart开始,长度为size的元素依次复制到数组a2的以targetStart为起始的单元中。
【例7.11】用arraycopy()方法复制两个数组。
class CopyArray
{static byte array1[ ]={97,98,99,100,101};
static byte array2[ ]={102,102,102,102,102};
public static void main(Sring[] args)
{
System.out.println(" array1="+new String(array1));
System.out.println(" array2="+new String(array2));
System.arraycopy(array1,0,array2,0,array1.length);
System.out.println(" array1="+new String(array1));
System.out.println(" array2="+new String(array2));
System.arraycopy(array1,0,array1,1,array1.length-1);
System.arraycopy(array2,1,array2,0,array2.length-1);
System.out.println(" array1="+new String(array1));
System.out.println(" array2="+new String(array2));
}
}
运行结果:
C:/>java CopyArray
array1=abcde
array2=fffff
array1=abcde
array2= abcde
array1=aabcd
array2=bcdee
(3)退出虚拟机
在用户的程序还未执行完之前,强制关闭Java虚拟机的方法是exit():
Public static void exit(int exitCode)
关闭虚拟机的同时把状态信息exitCode传递给操作系统,exitCoded非零时,表示非正常退出。
(4)强制垃圾收集
垃圾收集器一般情况下运行于后台,并自动地收集已不使用了的内存。使用gc()方法可强制垃圾收集器启动:
public static void gc()
3.环境属性
可以通过调用System.getProperty()方法来获得不同环境属性的值。例如下面的程序显示当前用户目录的路径:
class PlayUserDir{
public static void main(String[ ] args){
System.out.println(System.getProperty(" user.dir"));
}
}
可以通过setProperty( )方法设置系统属性的值:
public static String setProperty(String key,String value);
其中,key为键名,value为键值。
6.2.3 Math类
Math类提供了用于几何学、三角学以及几种一般用途方法的浮点函数,来执行很多数学运算。
1.Math类定义的两个双精度常量
doubleE--------常量e(2.7182818284590452354)
doublePI--------常量pi(3.14159265358979323846)
2.Math类定义的常用方法
Math类定义的方法是静态的,可以通过类名直接调用。下面简要介绍几类常用的方法。
①三角函数
public static double sin(double a)------三角函数正弦。
public static double cos(double a)------三角函数余弦。
public static double tan(double a)------三角函数正切。
public static double asin(double a)------三角函数反正弦。
public static double acos(double a)------三角函数反余弦。
public static double atan(double a)------三角函数反正切。
② 指数函数
public static double exp(double a)------返回ea的值。
public static double log(double a)------ 返回lna的值。
public static double pow (double y,double x)------ 返回以y为底数,以x为指数的幂值。
public static double sqrt(double a)------ 返回a的平方根。
③ 舍入函数
public static intceil(double a)------- 返回大于或等于a的最小整数。
public static intfloor(double a)------- 返回小于或等于a的最大整数。
以下三个方法都有其它数据类型的重载方法:
public static intabs(int a)------- 返回a的绝对值。
public static intmax(int a,int b)------- 返回a和b的最大值。
public static intmin(int a,int b)------- 返回a和b的最小值。
④其它数学方法
public static doublerandom( )------ 返回一个伪随机数,其值介于0和1之间。
public static doubletoRadians(doubleangle )------ 将角度转换为弧度。
public static doubletoDegrees (doubleangle)------ 将弧度转换为角度。
7.3 java.util包中的集合类
java.util是Java语言中另一个使用广泛的包,它包括集合类、时间处理模式、日期时间工具等各种常用工具。
Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。集合类中存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。
下面我们将介绍集合类中的几个常用类的使用。
6.3.1 Vector类
Java的数组具有很强的功能,但它并不总是能满足我们的要求。数组一旦被创建,它的长度就固定了。但是,有时我们在创建数组时并不确切地知道有多少项需要加进去。解决这一问题的办法是,创建一个尽可能大的数组,以满足要求,但这势必会造成空间的浪费。Java提供了一个好的办法:使用java.util包中的向量类Vector。
简单地说,Vector是一个动态数组,它可以根据需要动态伸缩。另外,Vector类还提供了一些有用的方法,如增加和删除元素的方法,而这些操作在数组中一般来说必须手工完成。
Vector类提供了三个属性,四个构造器和多种方法,下面分别做以介绍:
1.属性
protected int capacityIncrement--------当向量的大小超过容量时,向量容量的增长量。
protected int elementCount--------这个Vector对象中的组件数。
protectedObjected[ ] elementData--------存储向量的组件的数组缓冲区。
2.构造器
Vector( )--------构造一个空向量。
Vector(Collection c )--------构造一个包含给定集合中的元素的向量。
Vector(int initialCapacity )--------构造一个具有给定的初始容量的空向量。
Vector(int initialCapacity, int capacityIncrement )-------- 构造一个具有给定的初始容量和容量增量的空向量。
3. 常用的方法
① 向向量中添加对象
向一个向量中添加新对象有两种情况,可以用Vector提供的两种不同方法来实现:
void addElement(Object obj)-------- 在向量的最后增加一个元素。
void insetElementAt(Object obj,int index)-------- 在向量的指定位置插入一个元素。
② 从向量中删除对象
从向量中删除对象有三种情况,可以用Vector提供的三种不同方法来实现:
void removeAllElement( )--------删除向量中的所有对象。
void removeElement(Object ob)--------删除向量中一个指定的对象(仅删除第一次出现的对象)。
void removeElementAt( int index)--------删除向量中一个指定位置上的对象。
③ 搜索向量中的对象
有时我们需要得到向量中特殊位置上的对象或判断向量中是否包含某个对象,可以使用如下的方法:
Object firstElement( )--------返回这个向量的第一个对象。
Object lastElement( )--------返回这个向量的最后一个对象。
Object ElementAt(int index )--------返回这个向量中指定位置的对象。
Boolean contains(Object elem)--------如果这个对象在这个对象中,则返回true。
④获取向量的基本信息
int capacity( )--------返回这个向量的当前容量。
int size( )-------- 返回这个向量的对象个数。
【例7.12】使用Vector类的示例。
?import java.util.*
class VectorTest{
public static void main(Sring[] args){
Vector vec=new Vector(3);
System.out.println(" old capacity is"+vec.capacity());
vec.addElement(new Integer(1));
vec.addElement(new Integer(2));
vec.addElement(new Integer(3));
vec.addElement(new Float(2.78));
vec.addElement(new Double(2.78));
System.out.println(" new capacity is"+vec.capacity());
System.out.println(" new size is"+vec.size());
System.out.println(" first item is"+(Integer)vec.firstElement());
System.out.println(" last item is"+(Float)vec.lasttElement());
if(vec. Contains(new Integer(2)))
System.out.println(" found 2");
vec. removeElementAt(1);
if(vec.Contains(new Integer(2))){
System.out.println(" found 2");
else
System.out.println(" after deleting not found 2");
}
}
运行结果:
C:/>java VectorTest
old capacity is3
new capacity is6
new size is5
first item is1
last item is2.78
found 2
after deleting not found 2
7.3.2 Stack类
Stack是Vector的一个子类,它实现标准的后进先出堆栈。Stack 仅仅定义了创建空堆栈的默认构造函数。Stack包括了由Vector定义的所有方法,同时增加了几种它自己定义的方法,介绍如下:
boolean empty( )--------如果堆栈是空的,则返回true,当堆栈包含元素时,返回false。
Object peek( )-----------返回位于栈顶的元素,但是并不在堆栈中删除它。
Object pop( )------------返回位于栈顶的元素,并在进程中删除它。
Object push (Object element )---------将element压入堆栈,同时也返回element。
int search(Object element)---------在堆栈中搜索element,如果发现了,则返回它相对于栈顶的偏移量。否则,返回-1。
【例7.13】向堆栈中添加元素并弹出。
import java.util.*
classStackTest{
public static voidmain(Sring[] args){
Stack stack1=new Stack();//构造一个空堆栈stack1
try {
stack1.push(new Integer(0));
stack1.push(new Integer(1));
stack1.push(new Integer(2));
stack1.push(new Integer(3));
stack1.push(new Integer(4));
System.out.println((Integer)stack1.pop());
System.out.println((Integer)stack1.pop());
System.out.println((Integer)stack1.pop());
System.out.println((Integer)stack1.pop());
System.out.println((Integer)stack1.pop());
}
catch(EmptyStackException e){ }
}
}
运行结果:
C:/>java StackTest
4
3
2
1
0
7.3.3 Hashtable类
前面讲到的集合类是通过下标来确定元素的位置,集合中的对象有一定的顺序,而Hashtable(散列表)却不同,它通过另一种方式来确定对象的位置。它是映射集合的一种实现,提供了将一个对象与另一个对象相关联的方法。
Hashtable是Dictionary类的子类,Dictionary类是抽象类,与查字典操作类似,它要达到通过一个键(key)来查找元素的目的。Hashtable类也是通过键来查找对象,如何确定这个键值呢?首先,散列表为每个对象计算出一个整数,称为散列码,每个对象与其散列码一一对应;然后,用散列码与对象个数进行取模运算,计算出相对应的键。散列表中的对象就是通过这种方式一一放入的,所以在查询对象时,用同样的方式就可以快速定位对象在散列表中的位置。
Hashtable不仅实现了父类的方法,还有自己的方法,如conrainsKey(Object key)。
下面介绍几个常用的方法:
Object put(Object key, Object value)--------将关键字和值插入散列表中。如果key不在散列表中,返回null。如果key已存在于散列表中,则返回与key相连的前一个值。
Object get(Object key)--------返回包含与key相关联的值的对象。如果key不在散列表中,则返回一个空对象。
Object remove(Object key)--------删除key及其相应的值,返回与key相关联的值。如果key不在散列表中,则返回一个空对象。
boolean conrainsKey(Object key)--------用来检查形参对象是否是一个散列表的键,是则返回true,否则返回false。
另外,size()方法返回表中元素的个数,isEmply()方法判断表中是否包含有元素。
作为应用散列表的一个典型例子,可考虑用一个程序来检验Java的Math.random()方法的随机性到底如何。在理想情况下,它应该产生一系列完美的随机分布数字。但为了验证这一点,我们需要生成数量众多的随机数字,然后计算落在不同范围内的数字多少。散列表可以极大简化这一工作,因为它能将对象同对象关联起来(此时是将Math.random()生成的值同那些值出现的次数关联起来)。
【例7.14】用Hashtable来检验随机数的随机性。
import java.util.*;
class Counter {
int i = 1;
public String toString() {
return Integer.toString(i);
}
}
class Statistics {
public static void main(String[] args) {
Hashtable ht = new Hashtable();
for(int i = 0; i < 10000; i++) {
// Produce a number between 0 and 20:
Integer r = new Integer((int)(Math.random() * 20));
if(ht.containsKey(r))
((Counter)ht.get(r)).i++;
else
ht.put(r, new Counter());
}
System.out.println(ht);
}
}