实验9 常用系统类
9.1实验目的
(1)掌握字符串处理方法;
(2)了解Math类的数学方法的使用;
(3)熟悉各种数据类型包装类的使用;
(4)了解Vector类的使用。
9.2 知识要点
9.2.1 Object类
(1) Object类处于Java继承层次中最顶端的类,它封装了所有类的公共行为。
(2) Object类的equals()方法采用的是==运算比较,也就是只有两个引用变量指向同一对象时才相等。而实际上我们期望该方法进行对象的内容比较,因此子类中通常将equals()方法改写。
(3) Object类的toString()方法是返回对象的描述信息,在Object类中该方法返回对象的类名及对象引用地址。子类中通常要提供自己的toString()方法,以便更好描述对象。
9.2.2 Math类
(1)Math类中的方法和属性均为静态的,Math类不能创建对象。
(2)表9-1列出的Math类的方法不少提供了参数多态。
(3)方法random()产生的随机数的范围是0~1之间的不包括0和1的一个小数形式的数。
表9-1 Math类的常用方法
|
方法 |
功能 |
|
int abs(int i) |
求整数的绝对值 ;另有针对long,float,double的多态方法 |
|
double ceil(double d) |
不小于d的最小整数(返回值为double型) |
|
double floor(double d) |
不大于d的最大整数(返回值为double型) |
|
Int max(int i1,int i2) |
求两个整数中最大数;另有针对long,float,double的多态方法 |
|
Int min(int i1,int i2) |
求两个整数中最小数 ;另有针对long,float,double的多态方法 |
|
double random() |
0~1之间的随机数 |
|
Int round(float f) |
求最靠近f的整数 |
|
long round(double d) |
求最靠近d的长整数 |
|
double sqrt(double a) |
求平方根 |
|
double cos(double d) |
求d的cos函数 注:其它求三角函数的方法有sin,tan |
|
double log(double d) |
求自然对数 |
|
double exp(double x) |
求e的x次幂(ex) |
|
double pow(double a, double b) |
求a的b次幂 |
2.3 数据类型包装类
(1)每种基本数据类型均有对应的包装类,除char和int的包装类为Character和Integer外,其他类型的包装类的名字均为相应类型的关键字将首字符换大写(例如:long的包装类为Long).
(2) 包装类用来实现该类型数据的一些处理操作,尤其是其中的静态方法,见表9-2。
表9-2 数据包装类的常用方法
|
方法 |
功能 |
|
int Integer.parseInt(String s) |
将数字串转化为整数 |
|
long Long.parseLong(String s) |
将数字串转化为长整数 |
|
double Double.parseDouble(String s) |
将数字串转化为双精度数 |
|
boolean Character.isDigit(char c) |
判断某字符是否为数字 |
|
boolean Character.isLetter(char c) |
判断某字符是否为字母 |
|
String Integer.toString(int k) |
将一个整数转换为字符串 |
|
String Integer.toBinaryString(int k) |
将一个整数转换为二进制字符串 |
9.2.4 String类--字符串常量
(1)String类创建的字符串对象的内容不能改变;
(2)理解字符串的拼接运算的含义,可以将任何数据类型的数据与字符串进行拼接,包括对象类型的数据,它将调用对象的toString()的结果与串拼接。拼接的结果为一个新的串对象,不会改变源字符串对象的内容。例如:
String x="hello";
String x1=x; //x1和x指向同一串对象
String y="good";
x=x+y+2; //修改x的值,让其指向新生成的串。
System.out.println(x);
System.out.println(x1);
输出结果为:
hellogood2
hello
(3)String类提供了丰富的实例方法,见表9-3。
表9-3 String类的实例方法
|
方法 |
功能 |
|
boolean equals(Object obj) |
当前串与参数串比较是否相等 |
|
boolean equalsIgnoreCase(String s2) |
比较两个字符串,不计较字母的大小写 |
|
int length() |
求字符串长度 |
|
String trim() |
去除前导空格和尾部空格 |
|
int indexOf(int ch, int fromIndex)) |
从formIndex位置开始往后查找字符串中的字符ch的首次出现位置。 |
|
int indexOf(String s, int fromIndex)) |
从formIndex位置开始往后查找字符串中的子串的首次出现位置。 |
|
char charAt(int index) |
从串中获取指定位置的字符 |
|
String substring(int begin, int end) |
根据始末位置从串中获取子串 |
|
String[] split(String regex) |
按照分隔符将串分成若干子串 |
|
String replace(char ch1,char ch2) |
将字符串中所有ch1字符换为ch2 |
9.2.5 StringBuffer类—可变字符串
(1)StringBuffer类创建的串可以修改,可以对串的内容进行增、删、改操作。
(2)StringBuffer的常用方法,见表9-4。
表9-4 StringBuffer类的常用方法
|
方法 |
功能 |
|
StringBuffer append(Object obj) |
某个对象的串描述添加到 |
|
StringBuffer insert(int pos, Object obj) |
将某个对象的串描述插入到StringBuffer中的某个位置 |
|
StringBuffer setCharAt(int pos, char ch) |
用新字符替换指定位置字符 |
|
StringBuffer deleteCharAt(int pos) |
删除指定位置的字符 |
|
StringBuffer replace(int start, int end, String str) |
将参数指定范围的一个子串用新串替换 |
|
String substring(int start, int end) |
获取所指定范围的子串 |
9.2.6 Vector类
(1)类Vector实现了可扩展的对象数组,使用向量没有数组的范围限制,可以不断添加元素。但向量中不能存放基本数据类型的数据,加入的数据均为对象。
(2)向量的常用访问方法见表9-5。
表9-5 Vector类常用方法
|
方法 |
功能 |
|
void add(int index, Object element) |
将某个对象插入向量的指定位置 |
|
boolean add(Object o) |
将某个对象添加到向量中 |
|
void addElement(Object obj) |
将某个对象添加到向量中 |
|
int size() |
向量中已存放元素个数 |
|
void clear() |
删去所有元素 |
|
boolean contains(Object elem) |
检测向量中是否包含指定对象 |
|
Object get(int index) |
根据位置获取向量元素 |
|
int indexOf(Object obj, int start)
|
从指定位置起向后搜索对象obj,返回首次匹配位置 |
|
boolean remove(Object o) |
删去指定对象 |
|
void removeElementAt(int index) |
删去指定位置的元素 |
(3)对向量的遍历访问方法(设v为一向量)
方法1:通过位置访问
for (int k=0;k<v.size();k++)
输出 v.get(k);
方法2:通过使用迭代子进行遍历
Iterator p=v.iterator();
while (p.hasNext())
输出 p.next());
9.3 样例程序
样例1:编写一个方法统计一个字符在某字符串中的出现次数;从命令行参数获取一个算术表达式,利用前面方法判断该表达式的左右括号数量是否一致,如果一致,输出“YES”,否则输出“NO”。
【参考程序】
public class Count {
public static void main(String args[]) {
String s = args[0];
if ( count(s,’(‘ ) == count(s,’)’)) //看左括号与右括号的出现次数是否一样多
System.out.println(" YES" );
else
System.out.println(" NO" );
}
/* 统计字符c在串s中的出现次数 */
public static int count(String s ,char c) {
int x=0; //计数变量
for (int k=0;k<s.length();k++)
if (s.charAt(k)==c) x++; //在第k个位置出现,则计数增1
return x;
}
}
样例2:四位同学中一位做了好事,校长问这四位是谁做的好事。
A说:不是我。
B说:是C。
C说:是D。
D说:C胡说。
已知三个人说的是真话,一个人说的是假话。根据这些信息,找出做了好事的人。
【参考程序】
public class good
{
public static void main(String a[]){
char man; //做好事的人
String x="ABCD"; //A、B、C、D中的一个
for (int k=0;k<=3;k++) { //用循环去测试各种情形
int count=0;
man=x.charAt(k); //假设第k个是做好事者
if (man!='A') count++; //A说的话
if (man=='C') count++; //B说的话
if (man=='D') count++; //C说的话
if ( !(man=='D')) count++; //D说的话
if (count==3) //如果有3人说的是真话,则为要找结果,输出
System.out.println("this man="+man);
}
}
}
【说明】四个人中,每个人均有可能是做好事的人,所以用循环去测试,分别针对每种情形测试说真话的人的个数,如果count值为3,则为要找结果。
【编程技巧】
(1) 利用循环去测试每种可能性;
(2) 将每人说的话用逻辑表达。
(3) 统计说真话的人的计数变量赋初值0要放在循环内。
样例3:设有中英文单词对照表,输入中文单词,显示相应英文单词,输入英文单词显示相应中文单词。如果没找到,显示“无此单词”。
【参考程序】
public class Word{
public static void main(String args[]) {
String [][] x={ {"good","好"},{"bad","坏"},{"work","工作"}};
int k;
String in=args[0];
if ( (k=find_e(x,in))!=-1)
System.out.println(x[k][1]);
else if ((k=find_c(x,in))!=-1 )
System.out.println(x[k][0]);
else
System.out.println("无此单词");
}
/* 根据英文找中文,找到则返回所在行位置,未找到则返回-1 */
static int find_e(String [][] x, String y) {
for ( int k=0;k<x.length;k++)
if (x[k][0].equals(y))
return k;
return -1;
}
/* 根据中文找英文,找到则返回所在行位置,未找到则返回-1 */
static int find_c(String [][] x, String y) {
for ( int k=0;k<x.length;k++)
if (x[k][1].equals(y))
return k;
return -1;
}
}
【说明】这里为了简化问题,编写了两个方法,一个查找中文,一个查找英文。只要分别按中文和英文查找一遍即可,如果均为-1,则输出“未此单词”。
【编程技巧】
(1) 编写方法实现查找可增进程序的表达清晰;
(2) 如何将单词中英文对应关系用二维数组表达。
样例4:从键盘输入一个英文句子,统计该句子中英文单词的个数,将找出所有单词存放到一个数组中。例如:输入 He said, "That's not a good idea." 则输出为:
共有"+x.length+"个单词
He said that s not a good idea
【参考程序】
import java.io.*;
public class ListWords {
public static void main(String[] args) throws IOException {
String line;
char ch;
boolean isWord=false;
StringBuffer word=new StringBuffer();
System.out.println("输入一行文本:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
line=br.readLine();
for ( int i = 0; i < line.length(); i++ ) {
ch = line.charAt(i);
if ( Character.isLetter(ch) ) {
word.append(ch);
isWord=true;
}
else {
if ( isWord ) {
word.append(",");
isWord=false;
}
}
}
String x[]=word.toString().split(",");
System.out.println("共有"+x.length+"个单词");
for (int n=0;n<x.length;n++)
System.out.print(x[n]+ " ");
}
}
【说明】一个单词的判断条件是已字母开头,后跟若干字母。也就是遇到非字母的单词即可断定为单词结束。为了便于处理,这里将所有单词拼接到一个串中,单词之间用逗号分隔。程序中引入了一个逻辑变量isWord来标记当前处理字符是否为单词的部分,是则标记为true,不是则标记为false。本例也演示了split方法的使用,可以很方便地将一个字符串按指定分隔符分离出子串并存放到数组中。
【编程技巧】
(1) 定义一个StringBuffer类对象拼接所有单词,单词之间用逗号分隔。
(2) 抓住单词的特点,是连续若干字母,所以遇到字母即可将其作为单词的组成部分插入StringBuffer中。
(3) 定义一个逻辑变量记录前面是否出现单词,如果出现,则逻辑变量为true,否则为false。在处理非字母字符时通过判断该逻辑变量确定是否应插入一个逗号到StringBuffer中。
(4) 利用循环扫描处理整个字符串,在处理完毕后再将StringBuffer中的所有内容转化为String类对象,利用Split方法按逗号分隔分离出单词存入数组中。
样例5: 利用向量记录实现学生管理,能支持学生对象的增加、删除操作,每个学生对象包括学号、姓名、性别。删除学生必须输入学生的学号。
可以设计一个操作菜单,包括“增加”、“删除”、“显示”、“退出”4个选项。
import java.io.*;
import java.util.*;
public class student {
String name;
long stno;
String sex;
public student(String name,long stno,String sex) {
this.name=name;
this.stno=stno;
this.sex=sex;
}
public String toString() {
return "姓名:"+name+",学号:"+stno+",性别="+sex;
}
public static void main(String args[]) {
Vector group=new Vector();
outer: while (true) {
String ch=input("选择:1-- 增加, 2---删除, 3- 显示,4--退出");
int choice=Integer.parseInt(ch);
switch (choice) {
case 1: group.add(inputStudent());break;
case 2: long stno=Long.parseLong(input("请输入学号:"));
for (int k=0;k<group.size();k++ ) {
student x=(student)group.get(k);
if ( x.stno==stno)
group.removeElement(x);
}
break;
case 3: Iterator p=group.iterator();
while (p.hasNext())
System.out.println("==>"+p.next());
break;
case 4: break outer;
}
}
}
/* 从键盘输入一个字符串 */
public static String input(String hint) {
String x=null;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println(hint);
try {
x=br.readLine();
}catch(IOException e) { }
return x;
}
/* 从键盘输入一个学生 */
public static student inputStudent(){
String name=input("请输入姓名:");
long stno=Long.parseLong(input("请输入学号:"));
String sex=input("请输入性别:");
return new student(name,stno,sex);
}
}
【说明】 为了简化程序,设计了两个方法:
String input(String hint) : 根据提示从键盘获取一个字符串;
student inputStudent() :从键盘获取学生相关信息构造学生对象。
【编程技巧】
(1) 在输入数据的处理中编写方法,简化设计。
(2) 利用向量存储学生对象,查找数据时,要从向量中读取数据进行比较,获取对象时要强制转换才能赋给代表学生的引用变量。
(3) 程序演示了对向量的两种遍历处理方法。
9.4 上机练习
² 基本题
1)设有一个由10个英文单词构成的字符串数组,要求:
(1)统计以字母w开头的单词数;
(2)统计单词中含“or”字符串的单词数;
(3)统计长度为3的单词数。
2)输入一个算术表达式,例如:45*2+23*(234-24),求出其中有多少整常数。
3)创建一个程序,输出今天的年、月、日。
提示:创建一个java.util.Date类的对象代表当前的系统日期,使用对象的getYear()方法、getMonth()方法、getDay()方法可获得对应的年月日。
4)编写一个程序,用于计算 x op y这样的表达式的值,表达式从命令行输入,其中op 为 + - * / % 几种运算符之一,x和y代表两个实数。
5) 将以下程序补充完整
import java.util.Random;
public class Java_2 {
public static void main(String args[]){
Random random = new Random();
float x = random.nextFloat();//产生0.0与1.0之间的一个符点数
int n = Math.round(20*x);
//构造20以内的一个整数
long f = 1 ; //保存阶乘的结果
int k = 1 ; //循环变量
//*********Found********
do {__________;
k++;
//*********Found********
}__________
System.out.println(n+"!= "+f);
}
}
6) 将以下程序补充完整
//Java_1.java,字符串类的startsWith()和endsWith()方法
import javax.swing.*;
public class Java_1 {
public static void main( String args[] ){
String strings[] = { "started", "starting", "ended", "ending" };
String output = "";
//测试startsWith()方法
for ( int i = 0; i < strings.length; i++ )
if ( strings[ i ].startsWith( "st" ) )
output += "\"" + strings[ i ] + "\" 开始于 \"st\"\n";
output += "\n";
//从字符串第2个字符开始
for ( int i = 0; i < strings.length; i++ )
if ( strings[ i ].startsWith( "art", 2 ) )
output += "\"" + strings[ i ] + "\" 开始于 \"art\" 第2个字符位置\n";
output += "\n";
//测试endsWith()方法
for ( int i = 0; i < strings.length; i++ )
//*********Found********
if ( strings[ i ].endsWith( "____________" ) )
output += "\"" + strings[ i ] + "\" 结束于 \"ed\"\n";
JOptionPane.showMessageDialog( null, output,
"显示字符串类的比较",
//*********Found********
JOptionPane._________________________ );
System.exit( 0 );
}
}
² 提高题
1) 输入若干行文本,以end作为结束行,统计该文本由多少行组成,字符总数,有多少“the”,将整个文本中所有单词首字母为小写的改为大写输出。
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" };
输入一个小于100的整数,将其翻成英文表示。
例如:
输入32,输出:thirty two
输入14,输出:fourteen
输入8, 输出:eight
反之,输入英文表示,输出相应的整数(提高部分)。
3)将一个长字符串分成等长的若干行输出,除最后一行外,每行内容宽度为10。注意,每个汉字占用两个英文字符的宽度,判断字符为汉字的方法是汉字的编码值大于128。
9.5 思考题
1) 关于以下程序段,正确的说法是
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都不执行
2) 要产生[20,999]之间的随机整数使用哪个表达式?
A.(int)(20+Math.random()*979)
B. 20+(int)(Math.random()*980)
C. (int)Math.random()*999
D. 20+(int)Math.random()*980
3) 下列程序运行的结果为:
public class
Example{
String
str=new String("good");
char[] ch={'a','b','c'};
public static void main(String args[]){
Example ex=new Example();
ex.change(ex.str,ex.ch);
System.out.print(ex.str+" and ");
Sytem.out.print(ex.ch);
}
public void change(String str,char ch[]){
str="test ok";
ch[0]='g';
}
}
A. good and abc
B. good and gbc
C. test ok and abc
D. test ok and gbc
4) 设有如下程序
public class test
{
public static void main(String args[]) {
Integer intObj=Integer.valueOf(args[args.length-1]);
int i = intObj.intValue();
if(args.length > 1)
System.out.println(i);
if(args.length > 0)
System.out.println(i - 1);
else
System.out.println(i - 2);
}
}
运行程序,输入如下命令:
java test 2
则输出为:
A. test B. test -1 C. 0
D. 1 E. 2
5) 下列程序运行的结果为:
public class test
{
public static void main(String args[]) {
int i;
float f = 2.3f;
double d = 2.7;
i = ((int)Math.ceil(f)) * ((int)Math.round(d));
System.out.println(i);
}
}
A. 4 B. 5 C. 6
D. 6.1 E. 9
6)如果以下条件成立,则用到java.lang.Math 类中哪个方法?
method( -4.4 ) == -4;
A. round() B. min() C. trunc() D. abs()
E. floor() F. ceil()
7) set集合如何处理重复元素
A.如果加入一个重复元素将抛出异常
B.如果加入一个重复元素add方法将返回false
C. 集合通过调用equals方法可以返回包含重复值的元素。
D. 重复值将导致编译出错。
8) 以下哪个方法是Vector类中增加一个新元素的方法。
A.addElement B. insert C. append D. addItem
9) 以下哪些方法是Collection 接口的方法?
A. iterator B. isEmpty C. toArray D. setText