Java基础知识_1
No.1
类名和方法名
命名要求:
类名:以英文字母开头,后接字母、数字和下划线的组合。习惯以大写字母开头
方法名:与类名类似,首字母习惯小写‘
No.2
基本数据类型
种类:
整数类型:byte,short,int,long
浮点数类型:float,double
字符类型:char
布尔类型:boolean
占用的字节数比较:
byte ┌───┐
└───┘
short ┌───┬───┐
└───┴───┘
int ┌───┬───┬───┬───┐
└───┴───┴───┴───┘
long ┌───┬───┬───┬───┬───┬───┬───┬───┐
└───┴───┴───┴───┴───┴───┴───┴───┘
float ┌───┬───┬───┬───┐
└───┴───┴───┴───┘
double ┌───┬───┬───┬───┬───┬───┬───┬───┐
└───┴───┴───┴───┴───┴───┴───┴───┘
char ┌───┬───┐
└───┴───┘
取值范围:
- byte:-2^7 至 2^7-1 ,既 -128 ~ 127
- short: -2^15 至 2^15-1,既 -32768 ~ 32767
- int: -2^31 至 2^31-1,既 -2147483648 ~ 2147483647 (±2*10^10)
- long: -2^63 至 2^63-1,既 -9223372036854775808 ~ 9223372036854775807 (±9*10^19)
- float:符号位(1位)、指数位(8位)、尾数位(23位)
float的范围为-2^128 ~ +2^128,即 -3.40E+38 ~ +3.40E+38
- double:符号位(1位)、指数位(11位)、尾数位(52位)
double的范围为-2^1024 ~ +2^1024,即 -1.79E+308 ~ +1.79E+308
- boolean:理论上存储布尔类型只需要1 bit,但是通常JVM内部会把boolean表示为4字节整数
var:
Java 10 引入了var,如果想省略变量类型,可以使用var关键字定义变量,编译器会根据赋值语句自动推断出变量类型。
例如:var sb = new StringBuilder(); 编译器可以自动将var关键字识别为StringBuilder。
No.3
基本运算
1.整数运算:
+,-,*,/,=,+=,-=,*=,/=
% 取余,++ 自增, –自减,
<<n 左移n位,>>n 右移n位
byte和short会先转换为int再移位;>>>n会连同符号位一起移动n位
对整数的位运算:
& 与 两个数同时为1,结果才为1
| 或 只要任意一个为1,结果就为1
^ 异或 两个数不同,结果为1,否则为0
(对两个整数进行位运算,则按位对齐,然后依次对每一位进行运算)
优先级从高到低:
()
! ~ ++ —
* / %
+ –
<< >> >>>
&
|
= += -= *= /=
类型自动提升:
在运算过程中,如果参与运算的两个整型参数类型不一致,较小类型会自动转换为较大类型的整型。
强制转型:
可以使用 “(类型) 参数”将参数强制转型,实现将较大范围的整型转型为较小范围的整型
注意范围溢出,较大数值类型转为较小数值类型时只会保留低位)
2.浮点数运算
与整数运算区别:
浮点数运算和整数运算相比,只能进行加减乘除这些数值计算,不能做位运算和移位运算。
浮点数重要的特点:
常常无法精确表示。
说明:
比如,0.1在计算机中是一串无限循环小数,0.5才能精确表示。
所以浮点运算常常会有误差。
比较两个浮点数是否相等,正确的比较方法是判断两个浮点数之差的绝对值是否小于一个很小的数。
如:double r = Math.abs(x – y);if (r < 0.00001) { // 可以认为相等} else { // 不相等}
Java的浮点数完全遵循IEEE-754标准。这也是绝大多数计算机平台都支持的浮点数标准表示方法。
浮点数运算,除数为0时:
浮点数运算在除数为0时不会报错。
但会返回几个特殊值:
NaN Not a Number,Infinity 无穷大,-Infinity 负无穷大。
如:
double d1 = 0.0 / 0; // NaN NaN表示Not a Number
double d2 = 1.0 / 0; // Infinity Infinity表示无穷大
double d3 = -1.0 / 0; // -Infinity -Infinity表示负无穷大
浮点数转为整型:
可以将浮点数强制转型为整数。
在转型时,浮点数的小数部分会被丢掉。
如果转型后超过了整型能表示的最大范围,将返回整型的最大值。
如果要进行四舍五入,可以对浮点数加上0.5再强制转型。
3.布尔运算
布尔运算是一种关系运算,包括以下几类:
比较运算 >,>=,<,<=,==,!=
与运算 &&
或运算 ||
非运算 !
优先级从高到低:
!
>
,>=
,<
,<=
==
,!=
&&
||
短路运算:布尔运算的一个重要特点是短路运算。如果一个布尔运算的表达式能提前确定结果,则后续的计算不再执行。
如:false && (表达式x)的结果总是false,所以表达式x不会执行
三元运算符:Java还提供一个三元运算符 b ? x : y。
它根据第一个布尔表达式的结果,分别返回后续两个表达式之一的计算结果(true返回前者,false返回后者)。
补充:计算 b ? 表达式x : 表达式y 时,如果b为true,则只计算表达式x的值,b为false则只计算表达式y的值。
No.4
字符、字符串、数组
字符类型简介:
char是基本数据类型,它是character的缩写。
占用空间:
Java使用Unicode表示字符,所以,英文字符和中文字符都占用两个字节。
Unicode编码:
要显示一个字符的Unicode编码,只需将char类型直接赋值给int类型即可,还可以直接用 \u
+Unicode编码 来表示一个字符。
如:int n1 = \’A\’; // 字母“A”的Unicodde编码是65
char c1 = \’\u0041\’; // c1=\’A\’,因为十六进制0041 = 等于十进制65
也可以将int强制转型:char c2 = (char)65; //c2=\’A\’,int类型65
字符串类型
特点:
和char类型不同,字符串类型String是引用类型。(引用类型 由类型的实际值引用 表示的数据类型,类似于指针。)
除了是一个引用类型外,还有个重要特点,就是字符串内容不可变。
修改String类时,改变的是String类型变量的指向,原字符串还在。
引用类型变量可以指向null,它表示不存在。
字符串的表示:
字符串使用双引号"..."
表示开始和结束,字符串中包含”(双引号)时,需要使用\(斜杠)对双引号进行转义
常见转义字符:
\”(→”),\\’(→\’),\\(→\),
\n(→换行符),\r(→回车符),\t(→Tab),
\u####(→一个Unicode编码的字符)
输入多行字符串:
从Java 13开始,字符串可以用”””…”””表示输入多行字符串。输入方式类似于/** ..*/。
多行字符串前面共同的空格会被去掉
四种创建方式:
创建新字符串对象时,关于“字符串”,new String(”字符串“),”字符串“+”字符串“,”字符串“+变量,这四种方式的区别,详见 Java中newString(“abc”)创建几个对象解释
总结:
”字符串“ 方式会先从字符串池中查找,没有匹配的字符串才会创建并返回新的引用;
new String(”字符串“) 方式总会返回新的引用;
”字符串“+”字符串“ 同第一种
”字符串“+变量 方式创建的字符串不会加入字符串池
关于intern()方法:
在调用这个方法时,JAVA虚拟机首先检查字符串池中 是否已经存在 与该对象值相等 的对象存在
如果有,则返回字符串池中对象的引用
否则,会先在字符串池中创建一个相同值的String对象,然后再将它的引用返回。
数组
基本类型数组:
定义方法:
定义一个数组类型的变量,使用、“类型[]”,例如,int[]
。
和单个基本类型变量不同,初始化数组变量必须使用new创建,如:new int[5]
表示创建一个可容纳5个int
元素的数组。
Java数组的特点:
初始化:数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false;
长度不变:数组一旦创建后,大小就不可改变。
其他:
数组是引用类型;数组的索引从0
开始;
可以用”数组变量名.length"
获取数组大小;如果索引超出范围,运行时将报错。
省略数组大小:
也可以在定义数组时直接指定初始化的元素,这样就不必写出数组大小,而是由编译器自动推算数组大小。
如:int[] ns = new int[] { 68, 79, 91, 85, 62 }; //// 编译器自动推算数组大小为5
还可以进一步简写为:int[] ns = { 68, 79, 91, 85, 62 };
引用类型数组:
如果数组的元素不是基本类型,而是一个引用类型(如String类型),那么修改数组元素只会修改引用。
如:”String[] names = { "ABC", "XYZ", "zoo};" names[1]="Z";
// 修改元素names[1],只是让names[1]指向其他的引用,不再指向"XYZ"而已。
No.6
输入和输出
输出:
println():
可以使用System.out.println()输出一行。
println
是print line的缩写,表示输出并换行。
格式化输出(自动)
Java还提供了格式化输出的功能。为什么要格式化输出?因为计算机表示的数据不一定适合人来阅读:
如:double d = 12900000; System.out.println(d); // 输出会变成1.29E7
printf() :
如果要把数据显示成我们期望的格式,就需要使用此功能。
格式化输出使用”System.out.printf()";,通过使用占位符
%?
可以把输出格式化为指定格式:
如:double d = 3.1415926; System.out.printf(“%.2f\n”, d); // 保留两位小数→3.14
占位符:
Java的格式化功能提供了多种占位符,可以把各种数据类型“格式化”成指定的字符串。
占位符包括:
占位符 说明
%d 格式化输出整数
%x 格式化输出十六进制整数
%f 格式化输出浮点数
%e 格式化输出科学计数法表示的浮点数
%s 格式化字符串
其他说明:
%o —— oct 八进制 %d —— dec 十进制 %x —— hex 十六进制 %u —— 无符号整数
%f —— 保留小数点后面六位有效数字 %.3f,保留3位小数位
%e ——保留小数点后面六位有效数字,指数形式输出 %.3e,保留3位小数位,使用科学计数法
%g ——保证从最高位起,6位有效数字的前提下,使用小数方式;否则使用科学计数法
%.3g ——仅保留3位有效数字,使用小数或科学计数法(如,124.1表示为124,1241表示为1.24e+03)
%10s —— 右对齐,占位符10位 %-10s —— 左对齐,占位符10位
%.2s —— 截取2位字符串 %10.2s —— 10位占位符,截取两位字符串
%010d —— 10位占位符整数,空余位置用0填充
转义字符:
\n 换行,\v 纵向制表符,\t 横向制表符,
\r 回车,/f 换页,%% %。
format():
相对基本格式化输出采用‘%’的方法,”.format()”功能更强大。
输入:
和输出相比,Java的输入就要复杂得多。
步骤:
首先,导入Scanner类:import java.util.Scanner;
然后:创建Scanner对象:Scanner scanner = new Scanner(System.in);
最后:读取一行输入并获取字符串:
String name = scanner.nextLine(); // 读取一行字符串输入
int age = scanner.nextInt(); // 读取一行整数输入
double d = scanner.nextDouble() //读取一行double类型浮点数输入
No.7
if判断
简介:
在Java程序中,如果要根据条件来决定是否执行某一段代码,就需要if
语句。
基本语法:
if (条件) {
// 条件满足时执行
} else {
// 条件不满足时执行
//可以没有else部分
}
当输入只有一行:
当if
语句块只有一行语句时,可以省略花括号{},但是一般不推荐。
if语句的串联:
可以将多个if ... else if ...
串联,效果等同于if … else { if … } 。
关于判断语句:
在Java中,判断值类型的变量是否相等,可以使用==运算符。
判断引用:
判断引用类型 的变量是否相等时,== 判断的是“引用是否相等”。
如:”hello”和”HELLO”.toLowerCase()指向的引用不同,所以使用 == 判断的结果是false。
(解释:因为”HELLO” .toLowerCase() 在执行后会创建新的String对象 )
所以,建议使用 equals() 方法判断引用是否相等。
避免s1为null:
执行语句s1.equals(s2)时,如果变量s1为null,会报NullPointerException。
不能确保s1不为null时,可以添加判断判断语句 s1 != null && … 回避错误。
No.8
switch 多重选择
简介:
switch语句根据switch (表达式)计算的结果,跳转到与”表达式”匹配的case结果,然后继续执行后续语句,直到遇到break结束执行。
如:switch (option) {
case 1:
System.out.println(“Selected 1”);
break;
case 2:
System.out.println(“Selected 2”);
break;
default:
System.out.println(“Not selected”);
break;
}
补充:
表达式可以是字符串,匹配时,比较的是“内容是否相等”。
如果”case n: “后面没有写”break;”,那么”case n:”的内容执行完后,会继续执行下一个个case的内容。
switch语句还可以使用枚举类型作为选项。
编译时的检查:
使用IDE时,可以自动检查是否漏写了break语句和default语句,方法是打开IDE的编译检查。
在Eclipse中,选择Preferences – Java – Compiler – Errors/Warnings – Potential programming problems,将以下检查标记为Warning:
\’switch\’ is missing \’default\’ case
\’switch\’ case fall-through
在Idea中,选择Preferences – Editor – Inspections – Java – Control flow issues,将以下检查标记为Warning:
Fallthrough in \’switch\’ statement
\’switch\’ statement without \’default\’ branch
使用switch
时,如果遗漏了break
,就会造成严重的逻辑错误,而且不易在源代码中发现错误。
->:
介绍:
从Java 14开始,switch
语句升级为更简洁的表达式语法(“case 选项 表达式 -> 语句; “、”case 选项 表达式 -> {语句1; …}”),
通过使用类似模式匹配(Pattern Matching)的方法,保证只有一种路径会被执行,并且不需要break
语句。
(注意新语法使用->
,没有穿透效应,不需要使用break,如果有多条语句,需要用{}
括起来。)
使用:
使用新的switch
语法,不但不需要break
,还可以直接返回值:
String fruit = “apple”;
int opt = switch (fruit) {
case “apple” -> 1;
case “pear”, “mango” -> 2;
default -> 0; // 注意赋值语句要以;结束
System.out.println(“opt = ” + opt); //执行结果:opt = 1
通过这种方法返回值时,如果需要通过复杂的语句获得并返回值,可以使用yield code;的形式。
yield的作用类似于return。
注:switch
的计算结果必须是整型、字符串、枚举类型;
No.9
while循环
简介:
Java提供了while
条件循环:
while (条件表达式) {
循环语句
}
以及do while
循环(先执行循环,再判断条件):
do {
执行循环语句
} while (条件表达式);
No.10
for循环
简介:
for循环是应用最广泛的循环,基本语法:
for (初始条件; 循环检测条件; 循环一次后更新计数器的方式) {
// 执行语句
}
其他:
计数器:通常不会在循环体内修改计数器,以免逻辑混乱。
变量范围:变量应该把访问范围缩到最小,所以计数器i一般定义在循环内。 ///202005221702
与while循环相比:for循环把更新计数器的代码统一放到了一起,不需要在循环体内更新变量i。
for each 遍历数组元素:
for (变量类型 变量名 : 数组名) {
//执行语句
//这种方式可以用“变量名”在循环中遍历“数组名”的所有元素
}
No.11
break和continue
break:
在循环过程中,可以使用break
语句跳出当前循环。
break语句总是跳出最近的一层循环
continue:
break
会跳出当前循环,也就是整个循环都不会执行了。
而continue
则是提前结束本次循环,然后直接继续执行下次循环。
No.12
数组操作
遍历:
可以通过数组名.length获取数组长度,for循环进行遍历。
如:
int[] ns = { 1, 4, 9, 16, 25 };
for (int i = 0; i < ns.length(); i++){…}
或简写为:
for (int n : ns){…}
数组排序:
简介:
对数组进行排序是程序中非常基本的需求。
常用的排序算法有冒泡排序、插入排序和快速排序等。
冒泡算法:
int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
for (int i = 0; i < ns.length – 1; i++) {
for (int j = 0; j < ns.length – i – 1; j++) {
if (ns[j] > ns[j+1]) {
int tmp = ns[j];
ns[j] = ns[j+1];
ns[j+1] = tmp;
}
}
}
Arrays.sort():
Java的标准库已经内置了排序功能,我们只需要调用JDK提供的Arrays.sort()就可以排序:
int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
Arrays.sort(ns);
补充:
引用类型数组排序时,修改的是引用顺序;
基本数据类型排序时,修改的是内存中的数据。
多维数组:
二维数组:
二维数组就是数组的数组。
二位数组指向一组连续的数组地址,数组地址指向一组连续的数据。
访问二维数组的某个元素需要使用array[row][col]。
输出二维数组:
要打印一个二维数组,可以使用两层嵌套的for循环:
for (int[] arr : ns) {
for (int n : arr) {
System.out.print(n);
}
}
或者使用Java标准库的Arrays.deepToString():
如:
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
System.out.println(Arrays.deepToString(ns));
输出结果:
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]