java-1
头文件
1 | import java.util.Arrays; |
学习笔记
++n/n++
1 | int n = 5, post = 1, pre = 1; |
上例中,++n 的值等于 n 自增后的值,即 6,所以 pre 最后得到的值为 7。n++ 的值等于 n 自增前的值,即 5,所以 post 最后得到的值为 6。
位移运算
1 | int n=7;//00000111=7 |
仔细观察可发现,左移实际上就是不断地×2,右移实际上就是不断地÷2。
位运算
位运算是按位进行与、或、非和异或的运算。
与运算的规则是,必须两个数同时为1
,结果才为1
:
1 | n = 0 & 0; // 0 |
或运算的规则是,只要任意一个为1
,结果就为1
:
1 | n = 0 | 0; // 0 |
非运算的规则是,0
和1
互换:
1 | n = ~0; // 1 |
异或运算的规则是,如果两个数不同,结果为1
,否则为0
:
1 | n = 0 ^ 0; // 0 |
关于转型
要注意,超出范围的强制转型会得到错误的结果,原因是转型时,int
的两个高位字节直接被扔掉,仅保留了低位的两个字节
浮点数
溢出
整数运算在除数为0
时会报错,而浮点数运算在除数为0
时,不会报错,但会返回几个特殊值:
NaN
表示Not a NumberInfinity
表示无穷大-Infinity
表示负无穷大
强制转型
可以将浮点数强制转型为整数。在转型时,浮点数的小数部分会被丢掉。如果转型后超过了整型能表示的最大范围,将返回整型的最大值。例如:
短路运算
布尔运算的一个重要特点是短路运算。如果一个布尔运算的表达式能提前确定结果,则后续的计算不再执行,直接返回结果。
因为false && x
的结果总是false
,无论x
是true
还是false
,因此,与运算在确定第一个值为false
后,不再继续计算,而是直接返回false
。
如果没有短路运算,&&
后面的表达式会由于除数为0
而报错,但实际上该语句并未报错,原因在于与运算是短路运算符,提前计算出了结果false
。
字符
还可以直接用转义字符\u
+Unicode编码来表示一个字符:
1 | // 注意是十六进制: |
字符串连接
Java的编译器对字符串做了特殊照顾,可以使用+
连接任意字符串和其他数据类型,这样极大地方便了字符串的处理。
1 | public class Main { |
多行字符串
从Java 13开始,字符串可以用"""..."""
表示多行字符串(Text Blocks)了。
1 | public class Main { |
输入
和输出相比,Java的输入就要复杂得多。
我们先看一个从控制台读取一个字符串和一个整数的例子:
1 | import java.util.Scanner; |
然后,创建Scanner
对象并传入System.in
。System.out
代表标准输出流,而System.in
代表标准输入流。直接使用System.in
读取用户输入虽然是可以的,但需要更复杂的代码,而通过Scanner
就可以简化后续的代码。
有了Scanner
对象后,要读取用户输入的字符串,使用scanner.nextLine()
,要读取用户输入的整数,使用scanner.nextInt()
。Scanner
会自动转换数据类型,因此不必手动转换。
要判断引用类型的变量内容是否相等,必须使用equals()
方法:
1 | public class Main { |
for each循环
for
循环经常用来遍历数组,因为通过计数器可以根据索引来访问数组的每个元素:
但是,很多时候,我们实际上真正想要访问的是数组每个元素的值。Java还提供了另一种for each
循环,它可以更简单地遍历数组:
1 | public class Main { |
label(类goto)
当我们需要跳出或结束多重循环时,除了在每一个循环体后面加一个break(continue)外,还可以通过label(标号)跳出多重循环(有点类似与goto语句),如下例:
1 | import java.util.Scanner; |
快速打印数组内容
Java标准库提供了Arrays.toString()
,可以快速打印数组内容
1 | import java.util.Arrays; |
关于面对对象编程
class的作用有点类似于struct
逐个读取string
1 | a=(int)str.charAt(i)-'0'; |