4. 数学函数、 字符和字符串
4.1常用数学函数
Java 在 Math 类中提供了许多实用的方法,来计算常用的数学函数。
这些方法分为三类:三角函数方法(trigonometric method)、指教函数方法(exponent method) 和服务方法(service method)。服务方法包括取整 、求最小值、求最大值、求绝对值和随机方法。除了这些方法之外,Math 类还提供了两个很有用的 double 型常量,PI ( π ) 和 E (自然对数的底)。可以在任意程序中用 Math.PI 和 Math.E 的形式来使用这两个常量。
4.1.1三角函数方法
sin、cos 和 tan 的参数都是以弧度为单位的角度。asin 和 atan的返回值是 - π /2 ~π /2 的一个弧度值,acos 的返回值在 0 到 π 之间。1° 相当于 π /180 弧度,90° 相当于 π /2 弧度,而 30° 相当于 π /6 弧度。
例如:
Math.toDegrees(Math.PI / 2) 返 回 90.0
Hath.toRadians(30)返 回 0.5236 (n/6)
Math.sin(O) returns 0.0
Math.sin(Math.toRadians(270)) 返 回 -1.0
Math,sin(Math.PI / 6) 返 回 0. 5
Math,sin(Math.PI / 2)返 回 1.0
Math.cos(0) 返 回 1.0
Math,cos(Math.PI / 6) 返 回 0.866
Math,cos(Math.PI / 2) 返 回 0
Math.asin(O.5)返 回 0.523598333 (n/6)
Math.acos(O.S) 返回 1.0472 (rt/3)
Math.atanfl.O) 返回 0.78S398 (n/4)
4.1.2 指数函数方法
例如:
Math.exp(l) 返回 2.71828
Math,log(Math.E) 返回 1.0
Math.loglO(lO) 返回 1.0
Math.pow(2, 3) 返回 8.0
Math.pow(3, 2) 返回 9.0
Math.pow(4.5, 2.5) 返回 22.9176S
Math.sqrt(4) 返回 2.0
Math.sqrt(lO.S) 返回 4.24
4.1.3 取整方法
例如:
Math.ceil(2.1) 返回 3.0
Math•ceil(2.0) 返回 2.0
Math.ceil(-2.0)返回 -2.0
Math.ceil(-2.1) 返回 -2.0
Math.floor(2.1) 返回 2.0
Math.floor(2.0) 返回 2.0
Math.floor(-2.0) 返回-2.0
Math.floor(-2.1)返回-3.0
Math.rint(2.1)返回 2.0
Math.rint(-2.0)返回 -2.0
Math.rint(-2.1) 返回-2.0
Math.rint(2.S) 返回 2.0
Math.rint(4.5) 返回 4.0
Math.rint(-2.5)返回 -2.0
Math,round(2.6f) 返回3 // Returns int
Math.round(2.0) 返回2 // Returns long
Math.round(-2.0f) 返回-2 // Returns int
Math.round(-2.6) 返回-3 // Returns long
Math.round(-2.4) 返回-2 // Returns long
4.1.4 min、max 和 abs 方法
min 和 max 方法用于返回两个数(int、long、float 或 double 型)的最小值和最大值。例如,max(4.4,5.0) 返回 5.0, 而 min(3,2) 返回 2。abs 方法以返回一个数(int、long、float 或 double 型)的绝对值。
例如:
Math.max (2, 3) 返回 3
Math.max (2. Sf 3) 返回 3.0
Math.min (2.5, 4.6) 返回 2.S
Math.abs(-2) 返回 2
Math.abs(-2.1) 返回 2.1
4.1.5 random 方法
可以使用random( )方法编写简单的表达式,生成任意范围的随机数。
例如:
(int)(Math.random( ) * 10) 返回 0 ~ 9 之间的一个随机整数
5O + (int)(Math.random( ) * 50) 返回 50 ~ 99 之间的一个随机整数
通常,
a + Math . random( ) * b 返回 a ~ a+b 之间的一个随机整数,不包括 a+b
4.2 字符数据类型和操作
字符数据类型表示单个字符。
除了处理数值之外,Java 还可以处理字符。字符数据类型 char 用来表示单个字符。字符型直接量用单引号括住。
考虑以下代码:
char letter = "A";
char numChar = "4";
第一条语句将字符 A 赋值给 char 型变量 letter。第二条语句将数字字符 4 赋值给 char 型变量 numChar。
注意:字符串直接量必须括在双引号中。而字符直接量是括在单引号中的单个字符。因此 "A" 是一个字符串,而 ’A’ 是一个字符。
4.2.1 Unicode 和 ASCII 码
计算机内部使用二进制数。一个字符在计算机中是以 0 和 1 构成的序列的形式来存储的。将字符映射到它的二进制形式的过程称为编码(encoding)。字符有多种不同的编码方式,编码表(encoding scheme)定义该如何编码每个字符。
Java 程序中,可以使用像 ‘X’、 ‘1’ 和 ‘$’ 这样的 ASCII 字符,也可以使用 Unicode 码。
例如,下面的语句是等价的:
char letter = 'A';
char letter = '\u0041';// Character A’s Unicode is 0041
两条语句都将字符 A 赋值给 char 型变量 letter。
注意:自增和自减操作符也可用在 char 型变量上,这会得到该字符之前或之后的 Unicode 字符。
例如,下面的语句显示字符 b。
char ch = 'a':
System.out.println(++ch):
4.2.2 特殊字符的转义序列
假如你想在输出时显示如下带引号的信息,你能编写如下所示的这条语句吗?
System.out.println("He said "Java is fun"");
答案是不能,这条语句有语法错误。编译器会认为第二个引号字符就是这个字符串的结束标志,而不知道如何处理剩余的字符。
为了解决这个问题,Java 定义了一种特殊的标记来表示特殊字符,如下表所示。
这种标记称为转义序列,转义序列由反斜杠( \ )后面加上一个字符或者一些数字位组成。比如,\t是一个表示 Tab 字符的转义符,而诸如 \u03bl的转义符用于表示一个 Unicode。转义序列中的序列号作为一个整体翻译,而不是分开翻译。一个转义序列被当作一个字符。所以,现在可以使用下面的语句输出带引号的消息:
System.out.println("He said \"Java is fun\"");
它的输出是:
He said "Java is fun"
注意: 符号 \ 和 "" 一起代表一个字符。
反斜杠 \ 被称为转义字符。它是一个特殊字符。要显示这个字符,需要使用转义序列 \\。比如,下面的代码:
System.out.println("\\t is a tab character");
显示
\t is a tab character
4.2.2 字符型数据与数值型数据之间的转换
char 型数据可以转换成任意一种数值类型,反之亦然。将整数转换成 char 型数据时,只用到该数据的低十六位,其余部分都被忽略。例如:
char ch = (char)0XAB0041; // The lower 16 bits hex code 0041 is
// assigned to ch
System.out.println(ch): // ch is character A
要将一个浮点值转换成 char 型时,首先将浮点值转换成 int 型,然后将这个整型值转换为 char 型。
char ch = (char)65.25; // Decimal 65 is assigned to ch
System.out.println(ch);//ch is character A
当一个 char 型数据转换成数值型时,这个字符的 Unicode 码就被转换成某个特定的数值类型。
int i=(int) 'A'; // The Unicode of character A is assigned to i
System.out.println(i); //i is 65
如果转换结果适用于目标变量,就可以使用隐式转换方式;否则,必须使用显式转换方式。例如,因为 'a' 的 Unicode 码是 97, 它在一个字节的范围内,所以就可以使用隐式转换方式:
byte b = 'a';
int i = 'a';
但是,因为 Unicode 码 \\FFF4 超过了一个字节的范围,所以下面的转换就是不正确的:
byte b= '\uFFF4';
为了强制赋值,就必须使用显式转换方式,如下所示:
byte b = (byte)'\uFFF4';
0 ~ FFFF 的任何一个十六进制正整数都可以隐式地转换成字符型数据。而不在此范围内的任何其他数值都必须显式地转换为 char 型。所有数值操作符都可以用在 char 型操作数上。如果另一个操作数是一个数字或字符,那么 char 型操作数就会被自动转换成一个数字。如果另一个操作数是一个字符串,字符就会与该字符串相连。例如,下面的语句:
int i= '2' + '3'; // (int)'2' is 50 and (int)'3' is 51
System,out.println("i is " + i); // i is 101
int j = 2 + 'a';// (int)'a' is 97
System.out.println("j is " + j); // j is 99
System.out.println(j + " is the Unicode for character "+ (char)j);
// 99 is the Unicode for character c
System.out.println("Chapter "+ '2');
显示结果
iis 101
j is 99
99 is the Unicode for character c
Chapter 2
4.2.3 字符的比较和测试
两个字符可以使用关系操作符进行比较,如同比较两个数字一样。这是通过比较两个字符的 Unicode 值实现的。比如:
'a ' < 'b ' 为 true, 因为 'a' (97)的 Unicode 值比 'b' (98)的 Unicode 值小。
'a ' < 'A' 为 false,因为 'a' (97)的 Unicode 值比 'A'(65)的 Unicode 值大。
'I' < '8' 为 true, 因为 'I' (49)的 Unicode 值比 '8' (56)的 Unicode 值小。
经常,程序中需要测试一个字符是数字、字母;大写字母,还是小写字母。如 ASCH 字符集所示,小写字母的 Unicode 是连续的整数,从'a '的 Unicode 开始,然后是 'b','c' … ,'z'。同理,对于大写字母和数字字符也是这样的。这个特征可以用于编写
测试字符的编码。比如,下列代码测试字符 ch 是大写字母、小写字母,还是数字字符。
if (ch >= 'A' && ch <= 'Z')
System.out.print1n(ch + " is an uppercase letter"):
else if (ch >= 'a' && ch <= 'z')
System.out.println(ch + " is a lowercase letter"):
else if (ch >= '0' && ch <= '9')
System.out.println(ch + " is a numeric character"):
为了方便,Java 的 Character 类提供了下列方法用于进行字符测试,如下表所示。
例如:
System.out.println("isDigit('a') is " + Character.isDigit('a'));
System.out.println("isLetter('a') is " + Character.isLetter('a'));
System.out.println("isLowerCase('a') is "+ Character.isLowerCase('a'));
System.out.println("isUpperCase('a') is "+ Character.isUpperCase('a'));
System.out.println("toLowerCase('T') is "+ Character.toLowerCase('T'));
System.out.println("toUpperCase('q') is "+ Character.toUpperCase('q'));
显示
isDigit( 'a' ) is false
isLetter( 'a') is true
isLowerCase( 'a' ) is true
isUpperCase( 'a' ) is false
toLowerCase( 'T' ) is t
toUpperCase( 'q' ) is Q
4.3 String 类型
char类型只能表示一个字符。为了表示一串字符,使用称为 String (字符串)的数据类型。例如,下述代码将 message 声明为一个字符串,其值为 "Welcome to Java":
String message = "Welcome to Java";
String 实际上与 System 类和 Scanner 类一样,都是 Java 库中一个预定义的类。String 类型不是基本类型,而是引用类型(reference type)。任何 Java 类都可以将变量表示为引用类型。使用引用类型声明的变量称为引用变量,它引用一个对象。这里,message 是一个引用变量,它引用一个内容为 Welcome to ]ava 的字符串对象。
下表列出了获得字符串长度、访问字符串中字符、连接字符串、转换字符串为大写或者小写,以及裁剪字符串的 String 方法。
4.3.1 求字符串长度
可以调用字符串的length( ) 方法获取它的长度。例如,下面代码
String message = "Welcome to Java";
System.out.println("The length of " + message + " is "+ message.length());
显示
The length of Welcome to Java is 15
注意:使用一个字符串时,往往是知道它的直接量值的。为方便起见,Java 允许在不创建新变量的情况下,使用字符串直接量直接引用字符串。这样,"Welcome to Java" . length( )是正确的,它返回15。注意,""表示空字符串,并且" ".length( ) 为 0。
4.3.2 从字符串中获取字符
方法 s.charAt(index)可用于提取字符串 s 中的某个特定字符,其中下标 index 的取值范围在 0 ~s.length( )-1之间。例如,message.charAt(0)返回字符 W, 如下图所示。注意,字符串中第一个字符的下标值是0。
注意:在字符串 s 中越界访问字符是一种常见的程序设计错误。为了避免此类错误,要确保使用的下标不会超过 s.length( ) - 1。例如,s.charAt(s.length( ))会造成一个StringlndexOutOfBoundsException异常。
4.3.3 连接字符串
可以使用 concat 方法连接两个字符串。例如,如下所示的语句将字符串 s1 和 s2 连接构成 s3:
String s3 = sl.concat(s2);
因为字符串连接在程序设计中应用非常广泛,所以 Java 提供了一种实现宇符串连接的简便办法。可以使用加号(+)连接两个或多个字符串。因此,上面的语句等价于:
String s3 = s1 + s2;
下面的代码将字符串 message、"and"和"HTML"组合成一个字符串:
String myString = message +"and" + "HTML";
回顾一下,加号(+)也可用于连接数字和字符串。在这种情况下,先将数字转换成字符串,然后再进行连接。注意,若要用加号实现连接功能,至少要有一个操作数必须为字符串。如果操作数之一不是字符串(比如,一个数字),非字符串值转换为字符串,并与另外一个字符串连接。这里是一些示例:
// Three strings are concatenated
String message = "Welcome ”+ "to" + "Java";
// String Chapter is concatenated with number 2
String s = "Chapter" + 2; // s becomes Chapter2
// String Supplement is concatenated with character B
String s1 = "Supplement" + 'B' ; // si becomes SupplementB
如果操作数都不是字符串,加号(+)是一个将两个数字相加的加法操作符。
增强的 += 操作符也可以用于字符串连接。例如,下面的代码将字符串"and Java is fun"添加到 message 变量中的字符串 "Welcome to ]ava"后面。
message += "and Java is fun";
因此,新的 message 是 “ Welccmie to Java and Java is fun”。
如果 i =1 并且 j=2 ,下面语句的输出是什么?
System.out.println("i + j is" + i + j);
输出是 "i+j is 12",因为"i+j is” 首先和 i 的值连接。要强制 i+j 先执行,将 i+j 放在括号里,如下所示:
System.out.println("i + j is" + (i+j));
4.3.4 字符串的转换
方法 toLowerCase( ) 返回一个新字符串,其中所有字母小写;方法 toUpperCase( ) 返回一个新字符串,其中所有字母大写。
例如:
"Welcome".toLowerCaseC)返回一个新字符串 welcome。
"Welcome".toUpperCase()返回一个新字符串 WELCOME。
方法 trim( )通过删除字符串两端的空白字符返回一个新字符串。字符 " "、\t、\f、\r、或者 \n 被称为空白字符。
例如:
"\t Good Night \n".triim( )返回一个新字符串 Good Night。
4.3.5 从控制台读取字符串
为了从控制台读取字符串,调用 Scanner 对象上的 next( ) 方法。例如,下面的代码就可以从键盘读取三个字符串:
Scanner input = new Scanner(System.in);
System.out.print("Enter three words separated by spaces:");
String s1 = input.next();
String s2 = input.next();
String s3 = input.next();
System.out.println("sl is " + s1);
System.out.println("s2 is " + s2);
System.out.println("s3 is " + s3);
显示
Enter three words separated by spaces: Welcome to Java
si is Welcome
s2 is to
s3 is Java
next( )方法读取以空白字符结束的字符串(即 ' ' 、'\t ' 、' f '、 '\r '或 '\n ')。可以使 用 nextLine( )方法读取一整行文本。nextLine( ) 方法读取以按下回车键为结束标志的字符串。例如,下面的语句读取一行文本:
Scanner input = new Scanner(System .in);
System.out.println("Enter a line:");
String s = input.nextLine();
System.out.println("The line entered is " + s);
显示
Enter a line: Welcome to Java
The line entered is Welcome to Java
注意:为了避免输入错误,不要在 nextByte( )、nextShort( )、nextlnt( )、nextLong( )、 nextFloat( )、nextDouble( ) 和 next( )之后使用 nextLine( )。
4.3.6 从控制台读取字符
为了从控制台读取字符,调用 nextLine( )方法读取一个字符串,然后在字符串上调用 charAt( 0 )来返回一个字符。例如,下列代码从键盘读取一个字符:
Scanner input = new Scanner(System.in);
System.out.print("Enter a character:");
String s = input.nextLine( );
char ch=s.charAt(0);
System.out.println("The character entered is " + ch);
4.3.7 字符串比较
String 类提供了如下表所示的方法,用于比较两个字符串。
比较两个字符串的内容是否相等,应该使用 equals 方法。例如,可以使用下面的代码比较两个字符串:
if (stringl.equals(string2)){
System,out.println("stringl and string2 have the same contents");
}else{
System.out.println("stringl and string2 are not equal");
}
例如,下面的语句先显示 true, 然后显示 false。
String sl = "Welcome to 3ava";
String s2 = "Welcome to Java";
String s3 = "Welcome to C++";
System.out.println(sl.equals(s2)); // true
System.out.println(sl.equals(s3)); // false
compareTo 方法也用来对两个字符串进行比较。例如,考虑下述代码:
sl.compareTo(s2)
如果 s1与 s2 相等,那么该方法返回值 0;如果按字典顺序(即以 Unicode 码的顺序) s1小于 s2, 那么方法返回值小于 0;如果按字典顺序 s1大于 s2,方法返回值大于 0。
方法 compareTo 返回的实际值是依据 s1和 s2 从左到右数第一个不同字符之间的距离得出的。例如,假设 sl为"abc",s2 为"abg", 那 么 sl.compareTo(s2)返回 -4。首先比较的是 sl与 s2 中第一个位置的两个字符( a 与 a)。因为它们相等,所以比较第二个位置的两个字符(b 与 b)。因为它们也相等,所以比较第三个位置的两个宇符(c 与 g>。由于字符 c 比字符 9 小 4, 所以比较之后返回-4。
注意:如果使用像 >、>=、<或 <= 这样的比较操作符比较两个字符串,就会发生语法错误。 替代的方法就是使用 s1.compareTo(s2)来进行比较。
如果两个字符串相等,equals 方法送回 true;如果它们不等,方法返因 false。 compareTo 方法会根据一个字符串是否等于、大于或小于另一个字符串, 分别返回 0、正整数或负整數。
String 类还提供了对字符串进行比较的方法 equalsIgnoreCase 和 compareToIgnoreCase。当比较两个字符串时,方法 equalsIgnoreCase 和 compareToIgnoreCase 忽略字母的大小写还可以使用 str.startsWith(prefix)来检测字符串 str 是否以特定前缀( prefix ) 开始,使用str.endsWith(suffix)来检测字符串 str 是否以特定后缀(suffix ) 结束,并且可以使用 str.contains(si)来检测是否字符串 str 包含字符串 si。例如,
"Welcome to Java".startsWith("we") returns false.
"Welcome to 3ava".endsWith("va") returns true.
"Welcome to Java".endsWith("V") returns false.
"Welcome to Java".contains("to") returns true.
"Welcome to Java".contains("To") returns false.
4.3.8 获得子字符串
方法 s.charAt(index) 可用于提取字符串 s 中的某个特定字符。也可以使用 String 类中的 substring 方法从字符串中提取子串,如下表所示:
例如:
String message = "Welcome to Java";
String message = message.substring(0, 11) + "HTML";
//字符串 message 变成了 Welcome to HTML.
4.3.9 获取字符串中的字符或者子串
String 类提供了几个版本的 indexOf 和 lastlndexOf 方法,它们可以在字符串中找出一个字符或一个子串,如下表所示:
例如:
"Welcome to Java".indexOf('W') returns 0.
"Welcome to Java".indexOf('o') returns 4.
"Welcome to Java".indexOf('o', 5) returns 9.
"Welcome to Dava".indexOf("come") returns 3.
"Welcome to Java".indexOf("Java", 5) returns 11.
"Welcome to Java".indexOf("java", 5) returns -1.
"Welcome to Java".1astlndexOf('W') returns 0.
"Welcome to Java".lastlndexOf('o')returns 9.
"Welcome to 3ava".1astlndexOf('o', 5) returns 4.
"Welcome to Java".1astlndexOf("come") returns 3.
"Welcome to Java".1astlndexOf("Java", 5) returns -1.
"Welcome to ]ava".lastlndexOf("]ava”)returns 11.
假设一个字符串 s 包含使用空格分开的姓和名。可以使用下面的代码从字符串中抽取姓和名。
int k = s.indexOf(' ');
String firstName = s.substring(O , k);
String lastName = s.substring(k + 1);
例如,如果 s 是 Kim Jones, 下图显示了如何抽取出姓和名。
4.3.10 字符串和数字间的转换
可以将数值型字符串转换为数值。要将字符串转换为 int 值,使用 Integer.parselnt 方法,如下所示:
int intValue = Integer.parseInt(intString);
intString 是一个数值型字符串,例如"123"。
要将字符串转换为 double 值,使用Double.parseDouble 方法,如下所示:
double doubleValue = Double.parseDouble(doubleString);
doublestring是一个数值型字符串,例如"123.45"。
如果字符串不是数值型字符串,转换将导致一个运行时错误。Integer 和 Double 类都包含在 java.lang 包中,因此它们是自动导入的。
可以将数值转换为字符串,只需要简单使用字符串的连接操作符,如下所示:
String s = number + "";
编译运算练习
1.
2.