1
关键字public称为访问修饰符,它用于控制程序的其他部分对这段代码的访问级别
2
关键字class表明Java程序中的全部部分都包含在类中,将类作为一个加载程序逻辑的容器,程序逻辑定义了应用程序的行为
3
类是构建所有Java应用程序和applet的构建块
4
Java应用程序中的全部内容都必须放置在类中
5
关键字class后面紧跟类名
6
类名以字母开头,后面跟字母和数字的任意组合,长度没有限制,但不能使用Java关键字作为类名,但可以包含关键字
7
类名是以大写字母开头的名词,如果名字由多个单词组成,每个单词的第一个字母都应大写
8
源代码的文件名必须与公共类的名字相同,并用.java作为扩展名
9
.class是字节码文件
10
在类的源文件中必须包含一个main方法,也可以将自定义的方法添加到类中,并且在main方法中调用它们
11
main方法必须声明为public
12
Java中的main方法必须是静态的,并且没有返回值(void)
13
Java是一种强类型语言,这就意味着必须为每一个变量声明一种类型
14
在Java中有8种基本类型,4种整型、2种浮点型、1种用于表达Unicode编码的字符单元的字符类型char、1种用于表示真值的boolean类型
15
Java有一个能够表示任意精度的算术包,通常称为“大数值”。虽然被称为大数值,但它并不是一种新的Java类型,而是一个Java对象
16
4种整型:byte(1字节)、short(2字节)、int(4字节)、long(8字节)
17
在Java中,整型的范围与运行Java代码的机器无关,从而解决了软件从一个平台移植到另一个平台,或者在同一个平台中的不同操作系统之间进行移植给程序员带来的诸多问题
18
长整型数值有一个后缀L(如4000000L)
19
十六进制数值有一个前缀0x(如0xCAFE)
20
八进制有一个前缀0,例如,010对应八进制中的8
21
从Java7开始,加上前缀0b就可以写二进制数。例如,0b1001就是9
22
Java没有任何无符号类型
23
2种浮点类型:float(4字节)、double(8字节)
24
float类型的数值有一个后缀F(例如:3.14F)。没有后缀F的浮点数值默认为double类型,也可以在浮点数值后面添加后缀D(例如:3.14D)
25
所有的浮点数值计算都遵循IEEE754规范,用于表示溢出和出错情况的三个特殊的浮点数值:
正无穷大
负无穷大
NaN(不是一个数字)
例如:一个正整数除以0的结果为正无穷大。计算0/0或者负数的平方根结果为NaN
26
浮点数值不适用于禁止出现舍入误差的金融计算中。例如,命令System.out.println(2.0-1.1)将打印出0.899999999999,而不是人们想象的0.9.其主要原因是浮点数值采用二进制系统表示,而在二进制系统中无法精确的表示分数1/10,就好像十进制无法精确地表示1/3一样。如果需要在数值计算中不含有任何舍入误差,就应该使用BigDecim类
BigDecimal a = BigDecimal.valueOf(10.0);
BigDecimal b = a.subtract(BigDecimal.valueOf(9.1));
System.out.println(b);//0.9
System.out.println(10.0-9.1);//0.9000000000000004
27
Unicode编码单元可以表示为十六进制值,其范围从\u0000到\Uffff
28
\b—退格 \t—制表 \n—换行 \r—回车
29
boolean(布尔)类型有两个值:false和true,用于判定逻辑条件。整型值和布尔值之间不能进行相互转换
30
在Java中,变量的声明尽可能地靠近变量第一次使用的地方,这是一种良好的程序编写风格
31
在Java中,利用关键字final指示常量
关键字final表示这个变量只能被赋值一次。一旦被赋值之后,就不能够再更改。习惯上,常量名使用全大写
32
在Java中,经常希望某个常量可以在一个类中的多个方法中使用,通常将这些常量称为类常量。可以使用关键字static final设置一个类常量
类常量的定义位于main方法放入外部。因此,在同一个类的其他方法中也可以使用这个常量。而且,如果一个常量被声明为public,那么其他类的方法也可以使用这个常量
33
在Java中必须使用final定义常量
34
在Java中,使用算术运算符+、-、*、/表示加减乘除运算
35
当参与/运算的两个操作数都是整数是,表示除法;否则,表示浮点除法。
36
整数的求余数操作(有时称为取模)用%表示(例如,15/2等于7,15%2等于1,15.0/2等于7.5)
37
整数被0除将会产生一个异常,而浮点数被0除将会得到无穷大或NaN结果
38
x = x + 4;等价于 x += 4;
通常将运算符放在赋值符的左侧
39
不建议在其他表达式的内部使用自增++,这样编写的代码很容易令人困惑,并且会 产生烦人的bug
40
逻辑与“&&”和逻辑或“||”是按照“短路”方式求值的。如果第一个操作数已经能够确定表达式的值,第二个操作数就不必计算了。
例如逻辑与“&&”,第一个表示式的值为false,结果就为假;逻辑或“||”,第一个表达式的值为true时,结果自动为真
41
Java支持三元操作符— ?:
x < y? “是” : “否”
比较x和y,满足表示式返回第一个,否则返回第二个
42
在处理整型数值是,可以直接对组成整数值的各个为进行操作
43
位运算符包括:&(与)、|(或)、^(异或)、~(非)
44
&和|运算符如果应用于布尔值,得到的结果也是布尔值。
45
&和|这两个运算符与&&和||的运算非常类似,只是不按照“短路方式计算。即在得到计算结果之前,一定要计算两个操作数的值”
46
“>>”和“<<”运算符将二进制位进行右移或左移操作
47
>>>运算符将用0填充高位;>>运算符用符号位填充高位。
48
Java中没有<<<运算符
49
对移位运算符右侧的参数需要进行模32的运算(除非左边的操作数是long类型,在这种情况下需对右侧操作数模64。)
例:1<<35与1<<3或8是相同的
50
在Math类中,包含了各种各样的数学函数
51
要想计算一个数值的平方根,可以用sqrt方法
double x = 4;
double y = Math.sqrt(x);
Systen.out.println(y);//prints 2.0
println方法和sqrt方法存在微小的差异。println方法操作一个定义在System类中的System.out对象。但是,Math类中的sqrt方法处理的不是对象,这样的方法被称为静态方法。
52
在Java中没有幂运算,因此需要借助于Math类的pow方法。
语句:double y = Math.pow(x,a);
将y的值设置为x的a次幂(x^a)。pow方法有两个double类型的参数,其返回结果也为double类型
53
Math类提供了一下常用的三角函数:
Math.sin
Math.cos
Math.tan
Math.atan
Math.atan2
还有指数函数以及它的反函数------自然对数以及以10为底的对数
Math.exp
Math.log
Math.log10
最后,Java还提供了两个用于表示π和e常量的近似值:
Math.PI
Math.E
54
不必再数学方法名和常量名前添加前缀“Math”,只要在源文件的顶部加上下面这行代码就可以:
import static java.lang.Math.*;
例如:System.out.println(“The square root of \u03C0 is” + sqrt(PI));
55
在Math类中,为了达到最快的性能,所有的方法都使用计算机浮点单元中的例程。如果得到一个完全可预测的结果比运行速度更重要的话,那么就应该使用StrictMath类
56
数值类型之间的合法转换
上述中有6个实心箭头,表示无信息丢失的转换;有3个虚箭头,表示可能有精度损失的转换。例如,123456789是一个大整数,它所包含的位数比float类型所能够表达的位数多。当将这个整型数值转换为float类型时,将会得到同样大小的结果,但却失去了一定的精度。
int n = 123456789;
float f = n;// f is 1.23456789E8
当使用上面两个数值进行二元操作时(例如n + f,n 是整数,f是浮点数),先要将两个操作数转换为同一种类型,然后再进行计算
如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型
否则,如果其中一个操作数是float类型,另一个操作数将会转换为float类型
否则,如果其中一个操作数是long类型,另一个操作数将会被转换为long类型
否则,两个操作数都将被转换为int类型
57
在必要的时候,int类型的值将会自动地转换为double类型,但是另一方面,有时也需要将double转换成int。在Java中,运行进行这种数值之间的类型转换
58
强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟待转换的变量名
例:
double x = 9.997;
int nx = (int)x;
这样,变量nx的值为9。强制类型转换通过截断小数部分将浮点值转换为整型
59
如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下,希望使用这种操作方式),那就需要使用Math.round方法:
double x = 9.997;
int nx = (int) Math.round(x);
现在,变量nx的值为10.当调用round的时候,仍然需要使用强制类型转换(int)。其原因是round方法返回的结果为long类型,由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能够将long类型转换成int类型
60
如果试图将一个数值从一种类型强制转换为另一种类型,而又超出了目标类型的表示范围,结果就会截断成一个完全不同的值。例如,(byte)300的实际值为44
61
不要在boolean类型与任何数值类型之间进行强制性转换,这样可以防止发生错误
62
只有极少数的情况才需要将布尔类型转换为数值类型,这时可以使用条件表达书 b? 1:0
63
运算符的优先级见下图。如果不使用圆括号,就按照给出的运算符优先级次序进行计算。
同一个级别的运算符按照从左到右的次序进行计算(除了表中给出的右结合运算符外)。例如,
由于&&的优先级比||的优先级高,所以表达式
a && b || c 等价于 (a&&b)|| c
又因为+=有右结合运算符,所以表达式
a += b += c 等价于 a +=(b += c)
也就是将b += c的结果(加上c之后的b)加到a上
64
有时候,变量的取值只在一个有限的集合内,可以自定义枚举类型
65
枚举类型包括有限个命名的值。例如,
enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE};
现在,可以声明这种类型的变量:
Size s = Size.MEDIUM;
Size类型的变量只能存储这个类型声明中给定的某个枚举值,或者null值,null表示这个变量没有设置任何值。
66
从概念上将,Java字符串就是Unicode字符序列
67
Java没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类,很自然地叫做String。
68
每个用双引号括起来的字符串都是String类的一个实例:
String e = " ";//an empty string
String greeting = “Hello”;
69
String类的substring
方法可以从一个较大的字符串提取出一个子串。例如:
String greeting = “Hello”;
String s = greeting.substring(0,3);
创建了一个由字符“Hel”组成的字符串
substring方法的第二个参数是不想复制的第一个位置。这里要复制位置0、1和2(从0到2,包括0和2)的字符。在substring中从0开始计数,直到3为止,但不包含3
substring的工作方法有一个有点:容易计算子串长度。字符串s.substring(a,b)的长度为b-a。例如,子串“Hel”的长度为3-0=3
70
与绝大多数的程序设计语言一样,Java语言允许使用+号连接(拼接)两个字符串
String expletive = “Expletive”;
String PG13 = “deleted”;
String message = expletive + PG13;
上述代码将“Expletivedeleted”赋给变量message(注意,单词之间没有空格,+号按照给定的次序将两个字符串拼接起来)
71
当将一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串,例如:
int age = 13;
String rating = “PG” + age;
rating设置为“PG13”
这种特性通常用在输出语句中。例如:
System.out.println("The answer is " + answer);
72
String类没有提供用于修改字符串的方法。如果希望将第69条笔记中的greeting的内容修改为“Help!”,不能直接地将greeting的最后两个位置的字符串修改为‘p’和‘!’。
那如何修改字符串呢?首先提取需要的字符,然后再拼接上替换的字符串:
greeting = greeting.substring(0,3) + “p!”;
上面这条语句将greeting当前值修改为“Help!”
73
由于不能修改Java字符串中的字符,所以在Java文档中将String类对象称为不可变字符串,如同数字3永远是数字3一样,字符串“Hello”永远包含字符H、e、l、l和o的代码单元序列,而不能修改其中的任何一个字符,不过可以修改字符串变量,如greeting,让它引用另一个字符串,这就如同可以将存放3的数值变量改成存放4一样
74
第73小结的做法是否会降低运行效率?看起来好像修改了一个代码单元要比创建一个新字符串更加简洁。答案是:也对,也不对。的确,通过拼接“Hel”和“p!”来创建一个新字符串的效率确实不高。但是,不可变字符串却有一个优点:编译器可以让字符串共享。可以想象将各种字符串存放在公共的存储池中。字符串变量指向存储池中相应的位置。如果复制一个字符串变量,原始字符串与复制的字符串共享相同的字符
75
检测字符串是否相等,可以使用equals方法检测两个字符串是否相等。表达式:
s.equals(t)
如果字符串s与字符串t相等,则返回true;否则,返回false。需要注意,s和t可以是字符串变量,也可以是字符串常量。例如,下列表达式是合法的:
“Hello”.equals(greeting)
要想检测两个字符串是否相等,而不区分大小写,可以使用equalsIgnoreCase方法。
“Hello”.equalsIgnoreCase(“hello”)
76
一定不能使用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放置在同一个位置上。当然,如果字符串放置在同一个位置上,它们必然相等。但是,完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上
String greeting = “Hello”;// initialize greeting to a string
if(greeting == “Hello”) …
//probably true
if(greeting.substring(0,3) == “Hel”)…
//probably false
如果虚拟机始终将相同的字符串共享,就可以使用= =运算符检测是否相等。但实际上只有字符串常量是共享的,而+或substring等操作产生的结果并不是共享的。因此,千万不要使用= =运算符测试字符串的相等性,以免在程序中出现糟糕的bug。从表面上看,这种bug很像随机产生的间歇性错误
77
Java中的compareTo方法与C语言中的strcmp(对字符串进行比较)完全类似,因此,可以这样使用:
if(greenting.compareTo(“Hello”) == 0)…
不过,使用equals看起来更为清晰
78
空串" “是长度为0的字符串。可以调用以下代码检查一个字符串是否为空:
if(str.length() == 0)
或
if(str.equals(” "))
空串是一个Java对象,有自己的串长度(0)和内容(空)。不过,String变量还可以存放一个特使的值,名为null,这表示目前没有任何对象与该变量关联。要检查一个字符串是否为null,要使用以下条件:
if(str == null)
有时要检查一个字符串既不是null也不为空串,这种情况需要使用以下条件:
if(str != null && str.length() != 0)
首先要检查str不为null,如果在一个null值上调用方法,会出现错误
79
Java字符串由char序列组成。char数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元。
大多数的常用Unicode字符串使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示
80
length方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量。例如:
String greeting = “Hello”;
int n = greeting.length(); //is 5
81
要想得到实际的长度,即代码点数量,可以调用:
int cpCount = greeting.codePointCount(0,greeting.length());
82
调用s.charAt(n)将返回位置n的代码单元,n介于0~s.length()-1之间。例如:
char first = greeting.charAt(0); //first is ‘H’
char last = greeting.charAt(4); //last is ‘o’
要想的到第i个代码点,应该使用下列语句
int index = greeting.offsetByCodePoints(0,i);
int cp = greeting.codePoinAt(index);
83
类似于C和C++,Java对字符串中的代码单元和代码点从0开始计数
84
有些时候,需要由较短的字符串构建字符串,例如,按键或来自文件中的单词。采用字符串连接的方式达到次目的的效率比较低。每次连接字符串,都会构建一个新的String对象,既耗时,又浪费空间。使用StringBuilder类就可以避免这个问题的发生
85
如果需要用许多小段的字符串构建一个字符串,那么应该按照下列步骤进行。首先,构建一个空的字符串构建器:
StringBuilder builder = new StringBuilder();
当每次需要添加一部分内容时,就调用append方法。
builder.append(ch); // append a single character
builder.append(str); // append a string
在需要构建字符串时就调用toString方法,将可以得到一个String对象,其中包含了构建器中的字符序列
String completedString = builder.toString();
86
要想对文件进行读取,就需要一个用File对象构造一个Scanner对象:
Scanner in = new Scanner(Paths.get(“myfile.txt”));
如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加一个额外的反斜杠:
“c:\mydirectory\myfile.txt”
要想写入文件,就需要构造一个PrintWriter对象。在构造器中,只需要提供文件名:
printWrite out = new PrintWrite(“myfile.txt”);
如果文件不存在,创建改文件
87
可以构造一个带有字符串参数的Scanner,但是Scanner将字符串解释为数据,而不是文件名。例如:如果调用:
Scanner in = new Scanner(“myfile.txt”);//ERROR?
这个Scanner会将参数作为包含10个字符的数据:‘m’,‘y’,‘f’等。在这个示例中所显示的并不是人们所期望的效果
88
不能在嵌套的两个块中声明同名的变量
89
如果基本的整数和浮点数精度不能够满足需求,那么可以使用java.math包中的两个很有用的类:BigInteger和BIgDecimal。这两个类可以处理包含任意长度数字序列的数值。
90
BigInteger类实现了任意精度的整数运算,BigDecimal实现了任意精度的浮点数运算。
使用静态的valueOf方法可以将普通的数值转换为大数值:
BigInteger a = BigInteger.valueOf(100);
不能使用人们熟悉的算术运算符(如+和×)处理大数值。而需要使用大数值类中的add和multiply方法。
BigInteger c = a.add(b);//c = a + b
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2))); // d = c * (b+ 2)
BigInteger a = BigInteger.valueOf(100);
System.out.println(a);//100
BigInteger b = BigInteger.valueOf(12);
BigInteger c = a.add(b);
System.out.println(c);//112
BigInteger d = c.multiply(b.add(BigInteger.valueOf(2)));
System.out.println(d);//1568
91
数组是一种数据结构,用来存储同一类数值的集合。通过一个整型下标可以访问数组中的每一个值
92
int[] a = new int[100];
这条语句创建了一个可以存储100个整数的数组。数组唱的不要求是常量:new int[n]会创建一个长度为n的数组
93
创建一个数字数组时,所有元素都初始化为0,boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊的值null,这表示这些元素(还)未存放任何对象
94
要想获得数组中的元素个数,可以使用 数组名.length
95
一旦创建了数组,就不能再改变它的大小(可以改变每一个数组元素)。如果经常需要在运行过程中扩展数组的大小,就应该使用另一种数据结构——数组列表(array list)
96
public class array {
public static void main(String[] args) {
int[] a = new int[4];
for (int i = 0; i < a.length; i++) {
a[i] = i + 1;
}
for(int element : a){
System.out.println(element);
}
// for (int i = 0; i < a.length; i++) {
// System.out.println(a[i]);
// }
}
}
for each 语句可以用来依次处理数组中的每个元素,而不必为指定下标值而分心,定义一个变量用于暂存集合中的每一个元素,并执行相应的语句,和传统的for循环同样的结论,不过for each循环语句显得更加简洁,不易出错(不必为下标的起始值和终止值操心)
97
for each循环语句的循环变量将会遍历数组中的每个元素,而不需要使用下标值
98
有一个更加简单的方式打印数组中的所有值,即利用Arrays类的toString方法。调用Arrays.toString(a),返回一个包含数组元素的字符串,这些元素被放置在括号内,并用逗号分开
import java.util.Arrays;
public class array {
public static void main(String[] args) {
int[] a = new int[4];
for (int i = 0; i < a.length; i++) {
a[i] = i + 1;
}
System.out.println(Arrays.toString(a));//[1, 2, 3, 4]
}
}
99
int[] smallPrimes = {1,2,3,4,5,6,7};
创建了数组对象并同时赋予初始值的简化书写形式,在使用这种语句时,不需要调用new
100
new int[] {1,2,3,4,5,6,7}
初始化一个匿名数组,这种表示法将创建一个新数组并利用括号中提供的值进行初始化,数组的大小就是初始值的个数
使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组,例如:
smallPrimes = new int[] {1,2,3,4,5,6,7};
这是下列语句的简写形式:
int[] anonymous = {1,2,3,4,5,6,7,8};
smallPrimes = anonymous;
在Java中,允许数组唱的为0.在编写一个结果为数组的方法时,如果碰巧结果为空,则这种语法形式就显得非常有用,此时可以创建一个长度为0的数组:
new elementType[0]
注意:数组长度为0与null不同