Java编程思想第4版学习笔记(二)
第三章 操作符 & 第四章 控制执行流程(流程控制语句)
第三章和第四章的内容主要是讲操作符和流程控制语句,Java的大多数操作符和流程控制语句都和C/C++的十分类似,因此把这两章内容汇成一章,挑出Java独特的地方进行学习。
第三章
知识点1:P39,3.2,操作符,优先级
Java操作符和其他语言一样,作用于操作数,产生新值。各个操作符的优先级和结合性类似C/C++。
这里有一些特殊的地方:
+ 操作符可以用于字符串,把字符串和其他对象连接在一起,比如String s = new String(); int i = 0;System.out.println(s+i+1.2); 这里+操作符发现自己的左操作数是String对象,右操作数不是,因此就会把右操作数转化为一个临时的String对象然后再和左操作数相加。
= 赋值操作符可以使左操作数 的对象引用 成为右操作数所引用对象的别名。String s = new String("123"); String s2 = new String("456"); s = s2; 之后,s和s2所引用的对象的值都会变成"456"。这一点也同样体现在函数的参数传递上。
== 判等关系操作符也是比较特殊的,当它的左右操作数都是对象引用的时候,它判断的是这两个引用是否引用了同一个对象,而不是它们引用的对象值是否相同。如果要想判断两个对象引用所引用的值是否相同,需要使用类中的equals成员函数。如果没有这个成员函数,你需要自己创造一个。基本类型则无此限制。
>>>无符号右移位运算符,比起右移运算符,无论操作的是数是否是正数,它每次都往左侧填0。
类型转换运算符,用法类似这样,(想转换成的类型)变量/对象/字面值。有些类型之间不能够互相转换,不过除了boolean,各个基本类型之间都能互相转换。也可以通过这种方式,把高精度类型的数转成低精度的类型,这种转换成为“窄化转换”。
类型提升。char,byte,short类型的值在参加计算时,会自动地转换成int类型,再进行计算。两个不同的基本类型做算术运算时,精度低的那个类型的值会自动提升为精度高的类型。
知识点2:第三章提到的一些类库和方法
类名:Random
所属包:java.util
方法一:构造函数,参数为种子,可以为空,如果为空则用当前时间做种子。
方法二:nextInt(),参数可以为空,也可以是一个整数,如有参数,这个函数将生成范围在[0~参数值)之间的随机数。如果参数为空,则无限制。类似地,还有nextFloat(),nextLong(),nextDouble()等方法。
方法:toBinaryString()
所属包:java.lang
所属类:Integer, Double等等基本类型的包装器类型中。
参数:toBinaryString属于哪个类,调用时就需要哪个类的对象作为参数。
返回值:String
作用:是一个静态函数成员,用于获得一个数值的二进制表示(字符串形式)。
字段:E
所属包:java.lang
所属类:Math
介绍:是一个代表自然对数的基数的double类型静态常量。
方法:round()
所属包:java.lang
所属类:Math
参数:float或者double 。
返回值:int(参数为float时)或long(参数为double时)。
作用:返回给定浮点数四舍五入之后的整数结果。
第四章
基本流程控制语句
选择分支:if-else,switch
循环语句:do..while,while,for,range for
跳出循环或switch内部:break
跳出单次循环:continue
第四章提到的一些其他的相关Java语法
静态方法Math.random();
可以产生0~1之间的随机值。
标签
一个标签形如:标签名:,比如label1:,只能在迭代语句之前使用,标签后面只能接空白或者迭代语句或者注释。在循环内部使用break 标签名;即可跳转到标签处并且不再进入刚跳出的循环。使用continue 标签名;,即可跳转到标签处,继续进行循环迭代。经常被用于想要马上跳出多层循环的情况。
二进制数字字面值
Java SE7中,可以在二进制字面值前面加0b代表一个二进制数值,比如int a = 0b10101101;
第三章 练习题
练习1:练习使用打印语句,略。
练习2:创建一个包含一个float域(字段)的类,并用这个类来展示别名机制。
1 class Test{ 2 float i; 3 } 4 5 public class MainTest { 6 public static void main(String[] args){ 7 Test t1 = new Test(); 8 Test t2 = new Test(); 9 10 t1.i = 111; 11 t2.i = 222; 12 13 System.out.println("ti.i = " + t1.i); 14 System.out.println("t2.i = " + t2.i); 15 16 t1 = t2; 17 18 System.out.println("ti.i = " + t1.i); 19 System.out.println("t2.i = " + t2.i); 20 21 t1.i = 233; 22 System.out.println("ti.i = " + t1.i); 23 System.out.println("t2.i = " + t2.i); 24 } 25 }
练习3:创建一个包含一个float域(字段)的类,并用这个类来展示方法调用时(参数传递时)的别名机制。
1 class Test{ 2 float i; 3 } 4 5 class FuncTest{ 6 static void func(Test t){ 7 t.i = 2.17F; 8 } 9 } 10 11 public class MainTest { 12 public static void main(String[] args){ 13 Test t = new Test(); 14 System.out.println("t.i = " + t.i); 15 FuncTest.func(t); 16 System.out.println("t.i = " + t.i); 17 } 18 }
练习4:编写一个计算速度的程序,它所使用的距离和时间都是常量。
1 class Func{ 2 static double speedNeeded(double length,double time){ 3 return length/time; 4 } 5 } 6 7 public class MainTest { 8 public static void main(String[] args){ 9 Func.speedNeeded(23.8,14.5); 10 } 11 }
练习5、6:创建一个名为Dog的类,它包含两个String域:name和says。在main方法中,创建两个不同的Dog类对象,一个名为spot,叫声Ruff!;另一个名为scruffy,叫声Wurf!,然后显示这两个对象的名字和叫声。
接着,创建一个新的Dog类引用,并对其赋值为spot,分别使用==和equals比较这个引用和spot引用,查看结果。
1 class Dog{ 2 String name; 3 String says; 4 5 void shows(){ 6 System.out.println("name: "+name+" Says: "+says); 7 } 8 } 9 10 public class MainTest { 11 public static void main(String[] args){ 12 Dog spot = new Dog(); 13 spot.name = "spot"; 14 spot.says = "Ruff!"; 15 16 Dog scruffy = new Dog(); 17 scruffy.name = "scruffy"; 18 scruffy.says = "Wurf!"; 19 20 spot.shows(); 21 scruffy.shows(); 22 23 Dog newDog = spot; 24 System.out.println(newDog==spot); 25 System.out.println(newDog.equals(spot)); 26 } 27 }
练习7:编写一个程序,模拟扔硬币的结果。
1 import java.util.*; 2 3 class Coin{ 4 static void test(){ 5 Random r = new Random(); 6 System.out.println(r.nextInt(2)==1?"正面":"反面"); 7 } 8 } 9 10 public class MainTest { 11 public static void main(String[] args){ 12 Coin.test(); 13 } 14 }
练习8:展示用16进制和8进制记数法(字面值)来操作long值(赋值),并显示其二进制结果。
1 public class MainTest { 2 public static void main(String[] args){ 3 long l1 = 0777; 4 long l2 = 0xC2B; 5 6 System.out.println(Long.toBinaryString(l1)); 7 System.out.println(Long.toBinaryString(l2)); 8 } 9 }
练习9:多种解,略。
练习10:编写一个具有两个常量值的程序,一个具有交替的二进制1和0,最低有效位是0,另一个也具有交替的二进制1和0,最低有效位是1。取这两个值,用按位运算符以所有可能的方式结合运算它们,然后使用二进制形式表示出来。
1 public class MainTest { 2 public static void main(String[] args){ 3 int number = 0; 4 for(int i =0 ;i<32;i+=2){ 5 number|=1; 6 number<<=2; 7 } 8 number|=1; 9 10 int number2 = 0; 11 number2=~number; 12 13 int r1 = number^number2; 14 int r2 = number|number2; 15 int r3 = number&number2; 16 17 System.out.println(Integer.toBinaryString(number)); 18 System.out.println(Integer.toBinaryString(number2)); 19 } 20 }
练习11:以一个最高位为1的二进制数字开始,用有符号的右移操作符对其进行右移,直至所有的二进制数都被移出为止,显示每一次移动的二进制结果。
1 public class MainTest { 2 public static void main(String[] args){ 3 int number = 0b1111111111111111111111111111111; 4 5 while(number!=0) 6 { 7 number>>=1; 8 System.out.println(Integer.toBinaryString(number)); 9 } 10 11 System.out.println(number); 12 } 13 }
练习12:以一个所有位都为1的二进制数字开始,先左移它,然后用无符号的右移操作符对其进行右移,直至所有的二进制数都被移出为止,显示每一次移动的二进制结果。
1 public class MainTest { 2 public static void main(String[] args){ 3 int number = 0b1111111111111111111111111111111; 4 5 number<<=1; 6 System.out.println(Integer.toBinaryString(number)); 7 8 while(number!=0) 9 { 10 number>>>=1; 11 System.out.println(Integer.toBinaryString(number)); 12 } 13 14 System.out.println(number); 15 } 16 }
练习13:编写一个方法,它以二进制方式显示char类型的值,使用多个不同的字符来展示它。
1 class CharShows{ 2 static void show(char c){ 3 int number = c; 4 System.out.println(Integer.toBinaryString(number)); 5 } 6 } 7 8 public class MainTest { 9 public static void main(String[] args){ 10 CharShows.show('a'); 11 CharShows.show('z'); 12 CharShows.show('0'); 13 CharShows.show('9'); 14 } 15 }
练习14:编写一个接收两个字符串参数的方法,用各种布尔值的比较关系来比较这两个不同的字符串,然后把结果打印出来,做!和!=比较和同时时,用equals做测试。在main()中用几个不同的字符串对象调用这个方法。
1 class Test{ 2 static void comp(String s1, String s2){ 3 System.out.println( "s1 == s2 : " + (s1==s2?"true":"false")); 4 System.out.println("s1 != s2 : " + (s1!=s2?"true":"false")); 5 System.out.println("s1.equals(s2) : " + (s1.equals(s2)?"true":"false")); 6 } 7 } 8 9 public class MainTest { 10 public static void main(String[] args){ 11 String s1 = new String("1234"); 12 String s2 = new String("12345"); 13 14 Test.comp(s1,s2); 15 } 16 }
第四章 练习题
练习1:打印1~100的值。
1 public class MainTest { 2 public static void main(String[] args){ 3 for(int i = 1;i<=100;++i){ 4 System.out.println(i); 5 } 6 } 7 }
练习2:产生25个int类型的随机数,对于每一个非末一个的随机值,使用if-else语句把它和紧随它生成的随机值对比,输出结果:是大于,小于,还是 等于。
1 import java.util.*; 2 3 public class MainTest { 4 public static void main(String[] args){ 5 int beforeNum = 0; 6 Random r = new Random(); 7 for(int i = 0;i<25;++i){ 8 int thisNum = r.nextInt(100); 9 System.out.println("new Number is : " + thisNum); 10 if(i!=0){ 11 if(beforeNum>thisNum){ 12 System.out.println("Before Number : "+beforeNum+" > thisNum : "+thisNum); 13 } 14 else if(beforeNum<thisNum){ 15 System.out.println("Before Number : "+beforeNum+" < thisNum : "+thisNum); 16 } 17 else{ 18 System.out.println("Before Number : "+beforeNum+" == thisNum : "+thisNum); 19 } 20 } 21 beforeNum = thisNum; 22 } 23 } 24 }
练习3:和环境有关的行为,略。
练习4:写一个程序,给出一个整数,判断它是否为素数(用for和%)。
1 class PrimeNumber{ 2 static boolean isPrimeNumber(int number){ 3 boolean flag = true; 4 if(number==2||number==3)return true; 5 else{ 6 for(int i = 2;i<=Math.sqrt(number)+1;++i){ 7 if(number%i==0) 8 { 9 flag = false; 10 break; 11 } 12 } 13 } 14 15 return flag; 16 } 17 } 18 19 public class MainTest { 20 public static void main(String[] args){ 21 System.out.println("2 "+(PrimeNumber.isPrimeNumber(2)?"is a PN":"is Not a PN")); 22 System.out.println("3 "+(PrimeNumber.isPrimeNumber(3)?"is a PN":"is Not a PN")); 23 System.out.println("4 "+(PrimeNumber.isPrimeNumber(4)?"is a PN":"is Not a PN")); 24 System.out.println("8 "+(PrimeNumber.isPrimeNumber(8)?"is a PN":"is Not a PN")); 25 System.out.println("17 "+(PrimeNumber.isPrimeNumber(17)?"is a PN":"is Not a PN")); 26 System.out.println("24 "+(PrimeNumber.isPrimeNumber(24)?"is a PN":"is Not a PN")); 27 } 28 }
练习5:多种解,略。
练习6:修改本章书上两个含有test方法的例子,让它们接受额外的两个参数begin和end,在测试testval时先判断它是否在begin和end之间(含begin和end)。
1 class IfElse1{ 2 static int result = 0; 3 static void test(int testval,int target,int begin,int end){ 4 if(testval>=begin&&testval<=end){ 5 if(testval>target){ 6 result = 1; 7 } 8 else if(testval<target){ 9 result = -1; 10 } 11 else result = 0; 12 } 13 } 14 } 15 16 class IfElse2{ 17 static int test(int testval,int target,int begin,int end){ 18 if(testval>=begin&&testval<=end){ 19 if(testval>target){ 20 return 1; 21 } 22 else if(testval<target){ 23 return -1; 24 } 25 else return 0; 26 } 27 return -1; 28 } 29 }
练习7:修改本章练习1,通过使用break关键词(或者return关键词),使其只输出范围为1~99的值。
1 public class MainTest { 2 public static void main(String[] args){ 3 for(int i = 1;i<=100;++i){ 4 System.out.println(i); 5 if(i==99){ 6 break; //return 7 } 8 } 9 } 10 }
练习8:写一个switch语句,为每个case打印一个消息。然后把这个switch语句放进for循环里,来测试每一个case。并测试case后面带break和不带break的差异。
1 public class MainTest { 2 public static void main(String[] args){ 3 for(int i = 0;i<3;++i){ 4 switch (i){ 5 case 0: 6 System.out.println("0"); 7 //break; 8 9 case 1: 10 System.out.println("1"); 11 //break; 12 13 case 2: 14 System.out.println("2"); 15 //break; 16 } 17 } 18 } 19 }
练习9:创建一个方法,接受一个整数参数,并显示从1~指定整数中的斐波那契数字,比如参数是5,则输出1、1、2、3、5。
1 class Feb{ 2 static void feb(int max){ 3 int num1 = 1; 4 int num2 = 1; 5 int newNum = 0; 6 7 System.out.println(1); 8 System.out.println(1); 9 10 while(max>=num1+num2){ 11 newNum = num1+num2; 12 num1 = num2; 13 num2 = newNum; 14 System.out.println(num2); 15 } 16 } 17 } 18 19 public class MainTest { 20 public static void main(String[] args){ 21 Feb.feb(5); 22 } 23 }
练习10:吸血鬼数字是指位数为偶数的数字,可以由一堆数字相乘得到,而这对数字各包含乘积一半位数的数字,其中从最初的数字中选取的数字可以任意排列。以两个0结尾的数字不属于吸血鬼数字。例如,1260=21*60,1827=21*87,2187=27*81。因此,1260、1827、2187都是吸血鬼数字。写一个程序,找出四位数的所有吸血鬼数字。
1 import java.util.*; 2 3 public class MainTest { 4 public static void main(String[] args) { 5 method(); 6 } 7 8 private static void method() { 9 int[] startDigit = new int[4]; 10 int[] productDigit = new int[4]; 11 for (int num1 = 10; num1 <= 99; num1++) 12 for (int num2 = num1; num2 <= 99; num2++) { 13 if ((num1 * num2) % 9 != (num1 + num2) % 9) 14 continue; 15 int product = num1 * num2; 16 startDigit[0] = num1 / 10; 17 startDigit[1] = num1 % 10; 18 startDigit[2] = num2 / 10; 19 startDigit[3] = num2 % 10; 20 productDigit[0] = product / 1000; 21 productDigit[1] = (product % 1000) / 100; 22 productDigit[2] = product % 1000 % 100 / 10; 23 productDigit[3] = product % 1000 % 100 % 10; 24 int count = 0; 25 for (int x = 0; x < 4; x++) 26 for (int y = 0; y < 4; y++) { 27 if (productDigit[x] == startDigit[y]) { 28 count++; 29 productDigit[x] = -1; 30 startDigit[y] = -2; 31 if (count == 4) 32 System.out.println(num1 + " * " + num2 + " : "+ product); 33 } 34 } 35 } 36 } 37 }