施工中
# Printing in Java
public class Hello { | |
public static void main (String[] args) { | |
System.out.println("Hello World!"); | |
System.out.print("Hello "); | |
System.out.print(" World!"); | |
} | |
} |
Hello World! | |
Hello World! |
print
与 println
使用于将文本输出到屏幕。其区别存在于:
print
下一行接在同一行输出;println
下一行会换行后输出。
如例子所示:首先使用 println
输出 Hello World!
后,第二行输出 System.out.print("Hello ");
将会换行输出。第三行输出由于上一行使用了 print
所以紧接着第二行一起输出,不会换行。
# 变量
# 定义变量
在 Java 中,我们需要先定义变量才能使用。例如:
int x = 1; | |
// 变量类型 变量名称 = 初始值; |
上述语句将一个 int
类型的变量取名为 x
,并赋予了初始值 1
。
如果没有设置初始值,则相当于给它指定了默认值 0
。例如 int x;
,x 默认等于 0
。
# 赋值
public class Main { | |
public static void main(String[] args) { | |
int x = 100; // 定义 int 类型变量 x,并赋予初始值 100 | |
System.out.println(x); // 打印该变量的值,观察是否为 100 | |
x = 200; // 重新赋值为 200 | |
System.out.println(x); // 打印该变量的值,观察是否为 200 | |
} | |
} |
100 | |
200 |
定义变量后,我们可以重新对变量赋值。如上所示,定义 x
初始值为 100
,在第一次打印后再赋值 200
。于是赋值后再次打印就变成了 200
。
在定义变量时,需要指定变量类型。而在重新赋值时变量已经存在了,不能重复定义。所以在重新赋值时不能指定变量类型,必须使用 变量名称 = 赋值;
。例如 x = 200;
。
我们也可以将变量赋值给其他变量,例如:
public class Main { | |
public static void main(String[] args) { | |
int x = 100; | |
int y = x; // 将 y 赋值变量 x 的值 | |
System.out.println(x); | |
System.out.println(y); | |
} | |
} |
100 | |
100 |
# 基本数据类型
变量类型 | 数据类型 | 数据范围 | 示例 |
---|---|---|---|
byte | 整数 | -128 ~ 127 | |
short | 整数 | -32768 ~ 32767 | |
int | 整数 | -2147483648~2147483647 | -5, 0, 3, 10, etc. |
long | 整数 | -9223372036854775808~9223372036854775807 | |
float | 浮点数 | -3.4E38 ~ 3.4E38 | |
double | 浮点数 | -1.7E308 ~ 1.7E308 | 0.15, -3.4, 114.514, etc. |
char | 字符 | 0 ~ 255 | A, B, etc. |
boolean | 布尔 | true or false | true, false. |
# 运算
使用以下字符进行运算:
+
加-
减*
乘/
除%
求余
Java 还提供了一些特殊的复合赋值运算:
++
x++ → x = x + 1--
x-- → x = x - 1+=
x += 2 → x = x + 2-=
x -= 2 → x = x - 2*=
x *= 2 → x = x * 2/=
x /= 2 → x = x / 2%=
x %= 2 → x = x % 2
要注意类似x++
与++x
的计算结果是不同的:++x
表示先加 1 再引用 n,即先执行,再生成值;x++
表示先引用 n 再加 1,即先生成值,再执行运算:
x = 0; | |
System.out.println(x++); //0 先生成值,再执行运算 | |
System.out.println(++x); //2 先执行运算,再生成值 |
# 整数运算
Java 的整数运算遵循四则运算规则,可以使用任意嵌套的小括号。
public class main { | |
public static void main(String[] args) { | |
int i = (100 + 200) * (99 - 88); // 3300 | |
int n = 7 * (5 + (i - 9)); // 23072 | |
int x = 12345 / 67; // 184 | |
int y = 12345 % 67; // 12345÷67 的余数是 17 | |
System.out.println(i); | |
System.out.println(n); | |
} | |
} |
整数运算永远是精确的,运算结果只能得到结果的整数部分。
整数的除法对于除数为 0 时运行时将报错,但编译不会报错。
整数类型不能表达有小数部分的数;整数运算速度快,占内存小;日常中整数运算多。
# 浮点数运算
浮点数运算和整数运算相比,只能进行加减乘除这些数值计算,不能做位运算和移位运算。
public class main { | |
public static void main(String[] args) { | |
double i = 1.0 / 10 | |
double n = 1 - 9.0 / 10 | |
// 观察 x 和 y 是否相等: | |
System.out.println(i); | |
System.out.println(n); | |
} | |
} |
在计算机中,浮点数虽然表示的范围大,但是,浮点数有个非常重要的特点,就是浮点数常常无法精确表示。
因为浮点数常常无法精确表示,需要将十进制先转换为二进制。因此,浮点数运算会产生误差。
在 Java 中, 10
和 10.0
是完全不同的数字。
# 强制类型转换
当浮点数和整数放在一起运算时,Java 会将整数转换成浮点数,然后进行浮点数运算。
强制性转换的优先级高于四则运算。在转型时,浮点数的小数部分会被丢掉。如果转型后超过了整型能表示的最大范围,将返回整型的最大值:
int n1 = (int) 12.3; // 12 | |
int n2 = (int) 12.7; // 12 | |
int n2 = (int) -12.7; // -12 | |
int n3 = (int) (12.7 + 0.5); // 13 | |
int n4 = (int) 1.2e20; // 2147483647 | |
double n5 = (double) 5 // 5.0 | |
// 可以直接将 int 转换为 double | |
int x = 5 | |
double y = x // 5.0 |
# 布尔运算
布尔 boolean
,永远只有 true
和 false
两个值。
# 关系运算
布尔运算是一种关系运算,包括以下几类:
- 比较运算符:
>
,>=
,<
,<=
,==
,!=
int age = readInt("Please type your age: "); // 读取用户输入 int | |
boolean areYou18 = age >= 18 && age < 18; // 判定是否成年 | |
System.out.println("Access: " + areYou18); // 18, 19 true; 17 false |
- 与运算
&&
(And)
x | y | x && y |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
在与运算中,所有都为 true
才会定义为 true
。
- 或运算
||
(Or)
x | y | x || y |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
在或运算中,如果其中一个为 true
,它将直接定义为 true
。
- 非运算
!
(Not)
boolean lightOn = true;
lightOn = !lightOn; // false
lightOn = !lightOn; // true
关系运算符的优先级从高到低依次是:
!
>
,>=
,<
,<=
==
,!=
&&
||
# 短路运算
因为 false && x
的结果总是 false
,无论 x
是 true
还是 false
,因此,与运算在确定第一个值为 false
后,不再继续计算,而是直接返回 false
。
public class Main { | |
public static void main(String[] args) { | |
boolean b = 5 < 3; | |
boolean result = b && (5 / 0 > 0); | |
System.out.println(result); | |
} | |
} | |
// 如果没有短路运算,&& 后面的表达式会由于除数为 0 而报错,但实际上该语句并未报错,原因在于与运算是短路运算符,提前计算出了结果 false。 |
类似的,对于 ||
运算,只要能确定第一个值为 true
,后续计算也不再进行,而是直接返回 true
。
# De Morgan's Laws
!(A && B) == !A || !B | |
!(A || B) == !A && !B |
Example:
A | B | A || B | !(A || B) |
---|---|---|---|
T | T | T | F |
T | F | T | F |
F | T | T | F |
F | F | F | T |
Example:
A | B | !A | !B | !(A && B) |
---|---|---|---|---|
T | T | F | F | F |
T | F | F | T | F |
F | T | T | F | F |
F | F | T | T | T |
# 引用类型
# String 字符串
Java 提供了 String 类来创建和操作字符串。
String x = "hello world"; | |
System.out.prinln(x); // hello world |
# 比较字符串
使用 .equals()
来识别字符串。例如:
String name = readLine("Name"); | |
if(name.equals("MOEQY")) { | |
System.out.println("WOW!"); | |
} |
# 输入
使用 import
将 java.util.Scanner
导入, import
必须放在源代码的开头。
import java.util.Scanner; |
导入后我们需要创建一个 Scanner
对象并传入 System.in
。 System.in
代表着一个标准的输入流,对应标准输出流 System.out
。
Scanner scan = new Scanner(System.in); |
之后我们就可以使用 next()
读取用户输入:
nextLine()
字符串nextInt()
整数nextDouble()
浮点数- 等等。
例如:
import java.util.Scanner; | |
public class Main { | |
public static void main(String[] args) { | |
Scanner scan = new Scanner(System.in); | |
System.out.println("输入一个整数:"); | |
int userInput = scan.nextInt(); | |
System.out.println("您输入的数字为:" + userInput); | |
} | |
} |
如果可以的话,在整个输入流程结束后。可以使用 .close()
关闭输入。这样能够减少当输入完成后所一直占用的资源。
但请注意一定要正确使用 .close()
,在某些时候会引发不能理解的错误。例如:
import java.util.Scanner; | |
public class Main { | |
public static void main(String[] args) { | |
Scanner scan = new Scanner(System.in); | |
int a = scan.nextInt(); | |
System.out.println(a); | |
scan.close(); | |
Scanner scan_2 = new Scanner(System.in); | |
int b = scan_2.nextInt(); | |
System.out.println(b); | |
scan_2.close(); | |
} | |
} | |
// 输入 1 的结果 | |
//Exception in thread "main" java.util.NoSuchElementException | |
//at java.util.Scanner.throwFor(Scanner.java:862) | |
//at java.util.Scanner.next(Scanner.java:1485) | |
//at java.util.Scanner.nextInt(Scanner.java:2117) | |
//at java.util.Scanner.nextInt(Scanner.java:2076) | |
//at test.CloseTest.main(CloseTest.java:13) |
这是因为 scan
与 scan_2
都是由 System.in
封装而来的,两个独立的对象用的是同一个输入流。
当调用 scan.close()
时,实际相当于将 System.in.close()
。
当创建 scan_2
时, System.in
已经关闭了。
解决方法是只在主函数的类中创建 Scanner
对象,在代码最后调用 .close()
即可。
# 循环
# for 循环
for
使用计数器实现循环。 for
循环会先初始化计数器,然后,在每次循环前检测循环条件,在每次循环后更新计数器。计数器变量通常命名为 i
。
public class Main { | |
public static void main(String[] args) { | |
for(int i = 0; int < 3; i++) // initial; test; increment | |
{ | |
System.out.println(i); | |
} | |
} | |
} |
0
1
2
# while 循环
while
循环就是让计算机根据条件做循环计算,在条件满足时继续循环,条件不满足时退出循环。
public class Main { | |
public static void main(String[] args) { | |
int sum = 0; // 累加的和,初始化为 0 | |
int n = 1; | |
while (n <= 100) { // 循环条件是 n <= 100 | |
sum = sum + n; // 把 n 累加到 sum 中 | |
n ++; //n 自身加 1 | |
} | |
System.out.println(sum); // 5050 | |
} | |
} |
5050
当 while
的条件为 true
时,它将永远循环。
# 判断
# if
在 Java 中使用 if
语句,使某一段代码需要根据条件来决定是否执行。
if (条件) { | |
// 条件满足时执行 | |
} | |
// 举例:判断是否为负数 | |
public class Main { | |
public void run() { | |
int number = readInt("Number: "); | |
if (number < 0) | |
{ | |
System.out.println("Number is negative"); | |
} | |
} | |
} |
# else
if
语句还可以编写一个 else
语句,当 if
条件无法满足时,将执行 else
的语句块。
public class Main { | |
public static void main(String[] args) { | |
int n = 70; | |
if (n >= 60) { | |
System.out.println("及格了"); | |
} else { | |
System.out.println("挂科了"); | |
} | |
System.out.println("END"); | |
} | |
} |
else
不是必须的。
也可以使用多个 else if
串联。例如:
public class Main { | |
public static void main(String[] args) { | |
int n = 70; | |
if (n >= 90) { | |
System.out.println("优秀"); | |
} else if (n >= 60) { | |
System.out.println("及格了"); | |
} else { | |
System.out.println("挂科了"); | |
} | |
System.out.println("END"); | |
} | |
} |
# break 与 continue
在 while
循环和 for
循环中,我们都可以使用 break
与 continue
语句。
# break
在循环过程中,可以使用 break 语句跳出当前循环。