JAVA学习(一)| JAVA快速入门
学习参考:https://www.liaoxuefeng.com/wiki/1252599548343744/1255883729079552
只记录不熟悉/需要注意的部分
数据类型⁍
Java基本数据类型占用的字节数:
1 |
|
byte
恰好就是一个字节,而long
和double
需要8个字节。
整型⁍
对于整型类型,Java只定义了带符号的整型,因此,最高位的bit表示符号位(0表示正数,1表示负数)。各种整型能表示的最大范围如下:
- byte:-128 ~ 127
- short: -32768 ~ 32767
- int: -2147483648 ~ 2147483647
- long: -9223372036854775808 ~ 9223372036854775807
浮点型⁍
对于float
类型,需要加上f
后缀。
1 |
|
浮点数可表示的范围非常大,float
类型可最大表示3.4x1038,而double
类型可最大表示1.79x10308。
常量⁍
如果加上final
修饰符,这个变量就变成了常量:
1 |
|
常量在定义时进行初始化后就不可再次赋值,再次赋值会导致编译错误。
常量的作用是用有意义的变量名来避免魔术数字(Magic number),例如,不要在代码中到处写3.14
,而是定义一个常量。如果将来需要提高计算精度,我们只需要在常量的定义处修改,例如,改成3.1416
,而不必在所有地方替换3.14
。
var关键字⁍
如果想省略变量类型,可以使用var
关键字:
1 |
|
编译器会根据赋值语句自动推断出变量sb
的类型是StringBuilder
。
整数运算⁍
自增/自减⁍
注意++
写在前面和后面计算结果是不同的,++n
表示先加1再引用n,n++
表示先引用n再加1。
(哪个在前面就是先做哪个)
移位运算⁍
- 左移1相当于*2,注意溢出
- 右移相当于/2,负数右移仍是负数
还有一种无符号的右移运算,使用>>>
,它的特点是不管符号位,右移后高位总是补0
,因此,对一个负数进行>>>
右移,它会变成正数,原因是最高位的1
变成了0
:
1 |
|
对byte
和short
类型进行移位时,会首先转换为int
再进行位移。
位运算⁍
找到一个数二进制里其中最右边一个“1”所在的位置⁍
该位置标为1
,其他位置为0
。例如14
(1110
),返回0010
即2
1 |
|
异或的妙用⁍
-
swap(a,b)
1
2
3a=a^b;
b=a^b;
a=a^b; -
一群数
int[] nums
中,只有一个数出现了奇数次,其他均出现偶数次,找到那个数n
把所有数相异或的结果就是n
1
2
3
4int n = 0;
for(int num:nums){
n ^= num;
} -
一群数
int[] nums
中,只有两个数出现了奇数次,其他均出现偶数次,找到那两个数a
和b
所有数异或为
n
,则n=a^b
。因为a!=b
所以num
的二进制上肯定有一位为1,用n
上最右边一个1rightOne
来区分a
和b
1
2
3
4
5
6
7
8
9
10
11
12
13
14int n = 0;
for(int num:nums){
n ^= num;
}
int rightOne = n & (~n+1) ;
int a = 0; //a在rightOne那一位上为0
for(int num:nums){
if((num&rightOne)==0){
a ^= rightOne;
}
}
int b = n^a;
运算优先级⁍
在Java的计算表达式中,运算优先级从高到低依次是:
()
!
~
++
--
*
/
%
+
-
<<
>>
>>>
&
|
+=
-=
*=
/=
关系运算符的优先级从高到低依次是:
!
>
,>=
,<
,<=
==
,!=
&&
||
浮点数运算⁍
浮点数表示问题⁍
浮点数常常无法精确表示。
浮点数0.1
在计算机中就无法精确表示,**因为十进制的0.1
换算成二进制是一个无限循环小数,**很显然,无论使用float
还是double
,都只能存储一个0.1
的近似值。
但是,0.5
这个浮点数又可以精确地表示。
1 |
|
强制转型⁍
可以将浮点数强制转型为整数。在转型时,浮点数的小数部分会被丢掉(即正数变小,负数变大)。如果转型后超过了整型能表示的最大范围,将返回整型的最大值。例如:
1 |
|
如果要进行四舍五入,可以对浮点数加上0.5再强制转型:
1 |
|
布尔运算⁍
- 短路运算
- 三元运算符(条件表达式)
表达式a?b:c
字符和字符串⁍
Unicode编码⁍
要显示一个字符的Unicode编码,只需将char
类型直接赋值给int
类型即可:
1 |
|
还可以直接用转义字符\u
+Unicode编码来表示一个字符:
1 |
|
【Java基础篇】Unicode、进制转换_cc的博客-CSDN博客_java unicode转16进制
方法 | 功能 |
---|---|
Integer.toBinaryString(int i) | 将十进制转换成二进制 |
Integer.toOctalString(int i) | 将十进制转换成八进制 |
Integer.toHexString(int i) | 将十进制转换成十六进制 |
Integer.toString(int i, int radix) | 将十进制转换成指定的进制 |
其他进制(字符串)转10进制Integer.parseInt(String s, int radix)
1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
// 请将下面一组int值视为字符的Unicode码,把它们拼成一个字符串:
int a = 72;
int b = 105;
int c = 65281;
String s = ""+(char)a+(char)b+(char)c; //""转换为字符串
System.out.println(s);
}
多行字符串⁍
从Java 13开始,字符串可以用"""..."""
表示多行字符串(Text Blocks)
多行字符串前面共同的空格会被去掉(以最短的对齐)
1 |
|
上述多行字符串实际上是5行,在最后一个DESC后面还有一个\n
。
数组⁍
初始化⁍
Java的数组有几个特点:
- 数组所有元素初始化为默认值,整型都是
0
,浮点型是0.0
,布尔型是false
; - 数组一旦创建后,大小就不可改变。
几种初始化表示方法
1 |
|
输入输出⁍
输出⁍
-
println
是print line的缩写,表示输出并换行。 -
print
不换行 -
printf
格式化输出 JDK文档java.util.Formatter占位符 说明 %d 格式化输出整数 %x 格式化输出十六进制整数 %f 格式化输出浮点数 %e 格式化输出科学计数法表示的浮点数 %s 格式化字符串 注意,由于%表示占位符,因此,连续两个%%表示一个%字符本身。
输入⁍
-
需要
import java.util.Scanner
-
创建
Scanner
对象传入System.in
- 要读取用户输入的字符串,使用
scanner.nextLine()
- 要读取用户输入的整数,使用
scanner.nextInt()
。 Scanner
会自动转换数据类型,因此不必手动转换。scanner.nextLine()
/nextInt()
/nextDouble()
/ …
1
2
3
4
5
6
7
8
9
10
11
12import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in); // 创建Scanner对象
System.out.print("Input your name: "); // 打印提示
String name = scanner.nextLine(); // 读取一行输入并获取字符串
System.out.print("Input your age: "); // 打印提示
int age = scanner.nextInt(); // 读取一行输入并获取整数
System.out.printf("Hi, %s, you are %d\n", name, age); // 格式化输出
}
} - 要读取用户输入的字符串,使用
条件选择⁍
判断引用类型相等⁍
要判断引用类型的变量内容是否相等,必须使用equals()
方法
注意:执行语句s1.equals(s2)
时,如果变量s1
为null
,会报NullPointerException
要避免NullPointerException
错误,可以利用短路运算符&&
,或者把一定不是null
的对象"hello"
放到前面:例如:if ("hello".equals(s)) { ... }
1 |
|
switch表达式⁍
普通用法跟c差不多
使用switch
时,如果遗漏了break
,就会造成严重的逻辑错误,而且不易在源代码中发现错误。
从Java 12开始,switch
语句升级为更简洁的表达式语法,使用类似模式匹配(Pattern Matching)的方法,保证只有一种路径会被执行,并且不需要break
语句。新语法使用->
,如果有多条语句,需要用{}
括起来。
1 |
|
1 |
|
yield⁍
大多数时候,在switch
表达式内部,我们会返回简单的值。
但是,如果需要复杂的语句,我们也可以写很多语句,放到{...}
里,然后,用yield
返回一个值作为switch
语句的返回值:
1 |
|
for each循环⁍
for each
循环,它可以更简单地遍历数组等所有“可迭代”的数据类型,包括后面会介绍的List
、Map
等
1 |
|
快速打印数组内容⁍
Java标准库提供了Arrays.toString()
,可以快速打印数组内容
数组排序⁍
可以直接使用Java标准库提供的Arrays.sort(数组)
进行排序,改变数组本身/引用
多维数组⁍
定义⁍
二维数组的每个数组元素的长度并不要求相同,例如,可以这么定义ns
数组:
1 |
|
这个二维数组在内存中的结构如下:
1 |
|
打印数组⁍
使用Java标准库的Arrays.deepToString()
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
命令行参数⁍
可以利用接收到的命令行参数,根据不同的参数执行不同的代码。例如,实现一个-version
参数,打印程序版本号:
1 |
|