目标一 Math类中的方法
在开发过程中运用java.lang.Math中的如下方法:abs ,ceil ,floor ,max ,min ,random ,round ,sin, cos, tan, sqrt。
本节需要注意的问题
Math类是不可被继承的,它里面的方法都是静态的。这或许是好事,因为它降低了了混乱情况发生的可能性。在这一块你几乎肯定会遇到问题,如果仅仅是因为你忽视它们而造成错误的发生,那将非常遗憾。
abs
因为我薄弱的数学基础,一开始我几乎对如何使用abs()这个方法的用法一无所知,直到为了通过Java程序员考试,我才开始认真学习弄懂它。它的作用是对一个数值进行取绝对值操作。因此下面的那段代码打印出来的数字是99。如果进行操作的数是一个非负数,它会原样返回。
System.out.println(Math.abs(-99));
ceil
这个方法返回的是比被操作数大的最小double 值。比如下面这个例子:
ceil(1.1)
它将返回2.0
如果你换成
ceil(-1.1)
它将返回 -1.0;
floor
参考一下JDK的说明文档,该方法返回的是:
返回最大的(最接近正无穷大)double 值,该值小于或等于参数,并且等于某个整数。
如果觉得这表达的不够清楚,那么我们可以看一下,下面那一小段代码和它的输出情况:
public class MyMat{
public static void main(String[] argv){
System.out.println(Math.floor(-99.1));
System.out.println(Math.floor(-99));
System.out.println(Math.floor(99));
System.out.println(Math.floor(-.01));
System.out.println(Math.floor(0.1));
}
}
它的输出是:
-100.0
-99.0
99.0
-1.0
0.0
max 和 min
注意一下这两个方法需要两个参数。你可能会有疑问,如果仅仅传递给它们一个参数会发生错误。你可以把这两个方法看成是:
“这两个数里面哪一个是最大的?”
以下的代码演示了这两个方法是如何工作的:
class MaxMin{
public static void main(String argv[]){
System.out.println(Math.max(-1,-10));
System.out.println(Math.max(1,2));
System.out.println(Math.min(1,1));
System.out.println(Math.min(-1,-10));
System.out.println(Math.min(1,2));
}
}
下面是输出的结果:
-1
2
1
-10
1
random
该方法返回的是一个0.0到1.0之间的随机数。
不像一些随机数系统,Java似乎并不支持提供种子数来增加随机性。这个方法可以用下面的方法来生成0到100之间的随机数。
从考试的角度来说,这个“返回一个0.0到1.0之间的随机数”的知识点是很重要的。因此下面的几个数字是可能输出结果:
0.9151633320773057 0.25135231957619386 0.10070205341831895
经常会遇到需要程序生成0到10之间或者0到100之间的随机数的情况。下面这行代码就是演示如何生成0到100之间的随机数:
System.out.println(Math.round(Math.random()*100));
round
返回最接近参数的一个整型数。如果小数部分大于0.5则返回下一个相对最小整数,如果小数部分小于等于0.5则返回上一个相对最大整数。如下例所示:
2.0 <=x < 2.5. then Math.round(x)==2.0 2.5 <=x < 3.0 the Math.round(x)==3.0
以下是一些例子和它们的输出:
System.out.println(Math.round(1.01));
System.out.println(Math.round(-2.1));
System.out.println(Math.round(20));
1
-2
20
sin cos tan
这三个方便快捷的方法都只需要一个 double型的参数,它们的功能和其他语言里面的方法功能是一样的。在我12年的编程工作中,我还从未使用过它们。可能需要记忆的仅仅是参数类型是double型的。
sqrt
返回该参数的double型平方根。
总结
max和min方法需要两个参数。
random方法返回的数值在0到1之间。
abs返回的是绝对值。
round返回最接近参数的整型数,但保留符号位。
练习题
习题 1) 下列哪个选项将会编译正确?
1) System.out.println(Math.max(x)); 2) System.out.println(Math.random(10,3)); 3) System.out.println(Math.round(20)); 4) System.out.println(Math.sqrt(10));
习题 2)下列哪个选项将会输出1到10之间的随机数?
1) System.out.println(Math.round(Math.random()* 10)); 2) System.out.println(Math.round(Math.random() % 10)); 3) System.out.println(Math.random() *10); 4) None of the above
习题 3)写面一行代码将会输出什么?
System.out.println(Math.floor(-2.1));
1) -2 2) 2.0 3) -3 4) -3.0
习题 4)写面一行代码将会输出什么?
System.out.println(Math.abs(-2.1));
1) -2.0 2) -2.1 3) 2.1 4) 1.0
习题 5)写面一行代码将会输出什么?
System.out.println(Math.ceil(-2.1));
1) -2.0 2) -2.1 3) 2.1 3) 1.0
习题 6)当你试图编译下列代码时将会发生什么?
class MyCalc extends Math{
public int random(){
double iTemp;
iTemp=super();
return super.round(iTemp);
}
}
public class MyRand{
public static void main(String argv[]){
MyCalc m = new MyCals();
System.out.println(m.random());
}
}
1) Compile time error 2) Run time error 3) Output of a random number between 0 and 1 4) Output of a random number between 1 and 10
练习题答案
答案1)
3) System.out.println(Math.round(20)); 4) System.out.println(Math.sqrt(10));
选项1错误是因为max方法只需要一个参数,而选项2错误是因为random方法只不需要参数。
答案2)
4) None of the above
最接近正确答案的是选项1,但是请别忘记一个细节就是,random方法返回的数据中包括0,而题目问的是1到10
答案3) 4) -3.0
答案4)
3) 2.1
答案5)
-
-2.0
答案6) 1) Compile time error
Math类是不可被继承的。这段代码有一些低级的错误。你只能在构造方法里面使用super,而它却是在random方法里面使用。
目标二 Strings的不变性
描述string对象不变性的重要性。
String类的不变性理论说明, string对象一旦被创建,它就决不能被改变。Java编程的一些经历意味着似乎并不如此。
如下面的代码所示:
public class ImString{
public static void main(String argv[]){
String s1 = new String("Hello");
String s2 = new String("There");
System.out.println(s1);
s1=s2;
System.out.println(s1);
}
}
如果Strings不能被改变,那么s1应该仍然打印出Hello,但是你如果运行这个程序段,你会发现第二次输出的字符串是“There”,这是为什么呢?
不变性实际上指的是字符串指针所指向的内容。在例子中,将s2赋给s1,字符串池中“Hello”字符串不再被指向,s1现在和s2指向同一个字符串。事实上“Hello”字符串没有被修改,理论上,你不能再获取到它了。
这个目标要求你认清strings的不变性,如果你想要改变字符串的内容的话,主要的方法就是采用StringBuffer类。
因为在后台实例化时,字符串连接会产生一个 新的字符串,所以当你的操作大量的字符串时,比如从读取一个大的文本文件时,性能就很重要了。通常字符串不变性并不影响每天的编程,但是在考试中它经常被 考到。记住不论怎么考,字符串一旦被创建,它本身就不会改变,即使指向它的指针指到别的字符串了。如果允许同一字符串再生,这就涉及到字符串在字符串池中 的创建方式了。5.2节在讲解在使用strings时=与equal的作用时,将这个内容作为一个部分涉及到了。虽然Java2和Java1.1都没有特别到这个内容,但是我认为一些问题的回答需要StrngBuffer的内容。
练习题
习题1)
已经创建了两个包含姓名的字符串,即:
String fname="John"; String lname="String"
你如果在同一个代码块中,改变这些字符串的值?
1) fname="Fred"; lname="Jones"; 2) String fname=new String("Fred"); String lname=new String("Jones"); 3) StringBuffer fname=new StringBuffer(fname); StringBuffer lname=new StringBuffer(lname); 4) 以上都不正确
习题2)
假如你写了一个程序用于读取8MB的文本文件。一行一行的读到一个String对象中,但是你发现执行性能不好。最可能的解释是?
-
Java I/O是围绕最慢的设备而设计的,它本身就很慢
-
String类不适合I/O操作,字符数组将更合适
-
因为String的不变性,每一次读要创建一个新的String对象,改为StringBuffer可能会提高性能
-
以上都不正确
练习题答案
答案1)
4)以上都不正确
一旦创建了一个String对象,它就只能读不能改变
答案2)
3)因为String的不变性,每一次读要创建一个新的String对象,改为StringBuffer可能会提高性能
我希望你们都不会像C程序员那样采用一个字符数据?
目标三 包装类
本目标主要讨论包装类的重要性,包括因为特定的需求选择最合适的包装类。讲述当一个包装类的的实例代码片段运行回产生什么结果。DoubleValue, floatValue, longValue,parseXxx,getXxx,toString,toHexString等等。
本节需要注意的问题
该目标的知识点明确在JDK1.4版本的考试中有明确规定,如果你看过以前的旧模拟题,你肯定不会看见里面包含本目标中的知识。因为在实际开发过程中你经常会用到本目标中的内容,所以学习起来会很容易。要特别仔细的学习这些知识点,你将会在真题库中看到它们的影子。
什么是包装类
Java中的基本类型的包装类提供了大量非常有用的公用方法。比如你需要往一个vetor里面存储一列整型数据,而Vetor里面存储的对象类型必须是Object而不是基本类型数据,当你从Vetor中将这些对象再取出来的时候,你得要用相应基本类型的包装类中的toxxValue公用方法来将对象强制转换成相应的基本类型的数据。下面的代码讲述了这种技巧:
import java.util.*;
public class VecNum{
public static void main(String argv[]){
Vector v = new Vector();
v.add(new Integer(1));
v.add(new Integer(2));
for(int i=0; i < v.size();i ++){
Integer iw =(Integer) v.get(i);
System.out.println(iw.intValue());
}
}
}
包装类提供了该对象与整形数据之间相互转换的公用方法,因此当你有一个String型的数据当你需要将它转换成它所代表的整型数据的时候,你可以使用包装类来完成这一系列操作。
包装类中提供的公用方法是静态的,所以你不需要实例化一个包装类的对象再对它里面的方法进行调用。当你对一个包装类赋值以后,你将不能再改边它。如果你在考试中遇到诸如Integer.setInt(int i)的表述,不用多想,这种方法是不存在的,它是错误的。
公用方法
一个最有用的包装类的公用方法是一些诸如parseXX的方法,它的作用是把一个String型的数据转换成一个它所对应的基本类型数据。XX代表包装类所能包括的数据类型。它包括parseInt, parseLong, parseShort, parseCharacter, parseBoolean。如果你在一个WEB页面里面有一个字段代表一个数据类型,
如果你有一个里面包含一个表格字段的WEB页面,返回的一个String型数据可以转化成一个数值。因此该字段可能包含"101"或者"elephant"。你可以试着用包装类将这些String型的数据转化成基本数据类型.如果它不能被适当的转化(比如其中包含"elephant"),一个NumberFormatException将会被抛出。
这里有一个例子,讲解了如何将一个可能可以转化成整型的String数据转化成整型数据,当转化不能进行的时候打印出错误信息。
包装类可以构造该包装类所包装的数据类型,以及可以转化为该类型的String型。所以Integer类型的包装类可以保存任何的整形数据,但是如果你试图将一个浮点数传递给它的时候一个错误将会发生。记住,包装类不是基本数据类型,它的实例的操作方式和其他对象是一样的。你可能对考试中出现的一些代码很疑惑,它们使用数学操作符对包装类的实例进行操作。你显然可以使用“+”来对包装类的实例进行操作,它会在后台调用toString方法。不过小心当你看到“-”, “%”和 “*”的时候。
public class String2Int{
public static void main(String argv[]){
try{
int i= Integer.parseInt(argv[0]);
System.out.println("Coverted to int val = " + i);
}catch(NumberFormatException nfe){ System.out.println("Could not covert to int");
}
}
}
toHexString
toHexString方法以十六进制的无符号整数形式返回一个整数参数的字符串表示形式。它有一个孪生的兄弟方法,它能够以二进制(基数 2)无符号整数形式返回一个整数参数的字符串表示形式。对这两个方法的用法理解需要对二进制数和十六进制数的概念有一定了解。你需要知道和对象相关的比特偏移的概念。下面的代码将会输出10接着100的串。
public class NumberFormats{
public static void main(String argv[]){
System.out.println(Integer.toBinaryString(4));
System.out.println(Integer.toHexString(16));
}
}
练习题
习题1) 下列哪项表述是正确的?
1) The Integer class has a String and an int constructor
2) The Integer has a floatValue() method
3) The wrapper classes are contained in the java.lang.Math package
4) The Double class has constructors for type double and float
习题2) 当你试图编译运行下列代码的时候会发生什么?
public class WrapMat{
public static void main(String argv[]){
Integer iw = new Integer(2);
Integer iw2 = new Integer(2);
System.out.println(iw * iw2);
System.out.println(iw.floatValue());
}
}
1 )Compile time error
2) Compilation and output of 4 followed by 2.0
3) Compilation and output of 4 followed by 2
4) Compile time error, the Integer class has no floatValue method
习题3) 当你试图编译运行下列代码的时候会发生什么?
public class TwoEms {
public static void main(String argv[]){
Object[] oa = new Object[3];
oa[0] = new Integer(1);
int i = oa[0];
System.out.print(i);
}
}
1) Compile time error an array cannot contain object references
2) Compile time error elements in an array cannot be anonymous
3) Compilation and output of 1
4) Compile time error Integer cannot be assigned to int
5) Compilation and output of the memory address of the Integer instance
习题4) 当你试图编译运行下列代码的时候会发生什么?
public class TwoPack {
public static void main(String argv[]){
Integer iw = new Integer(“2”);
Integer iw2 = new Integer(“2”);
String sOut = iw + iw2;
System.out.println(sOut);
}
}
1) Compile time error, the + operator cannot be applied to Integer
2) Compilation and output of 22
3) Compilation and output of 4
4) Compile time error, Integer has no String constructor
习题5) 下列哪段代码是正确的?
1) System.out.println(Integer.toBinaryString(4));
2) System.out.println(Integer.toOctalString(4));
3) System.out.println(Integer.add(2,2));
4) Float[] ar = new Float[] { new Float(1.0), new Float(2.1)};
练习题答案
答案 1)
1) Integer类有一个整型和String型的构造方法
2) Integer类有一个floatValue()方法
4) Double类有一个float型和double型的构造方法
答案 2)
1 )Compile time error
包装类的实例不能像基本数据类型那样进行操作,注意Integer确实有一个 floatValue方法
答案 3)
4) Compile time error Integer cannot be assigned to int
这段代码可以通过 Integer类的intValue 方法正常进行。 它是一个包装类对象不能赋给基本数据类型变量。
答案 4)
1) Compile time error, the + operator cannot be applied to Integer
包装类的实例不能像基本数据类型那样进行操作,它们是对象的实例,你必须将起进行转换成基本数据类型来进行数学操作。
答案 5)
1) System.out.println(Integer.toBinaryString(4));
2) System.out.println(Integer.toOctalString(4));
4) Float[] ar = new Float[] { new Float(1.0), new Float(2.1)};
包装类的实例不能像基本数据类型那样进行操作,因此选项3中的add方法不存在。如果年纪需要那样操作,你需要将其转化成基本数据类型。