写在前面:
- Focus
- Keep your mind clean
- Beginners mind.
- No Ego.
- There is no career goal.
- Shut up.
- Mindfulness. Care. Awareness
- There is no Boss
- Do something else
- There is nothing special.
0 Java语言概要
0.0 发展
从1994年詹姆斯高斯林和他的团队Sun开发的无意开发的嵌入式语言Oak开始,到如今Sun被Oracle收购后,在跨平台方面与服务器方面有着巨大的成就,成为最流行的语言之一。
0.1 分类
- JavaSE (Java Standard Edition)
- JavaEE (Java Enterprise Edition)
- JavaME (Java Micro Edition)
0.2 特点——跨平台
所有的Java程序都运行在Java虚拟机(JVM)上,在不同的操作系统上都拥有这不同的JVM,这使得所写的一份代码,在经过编译器编译之后,生成的直接字节码可以在任何平台上运行。但是,一个Java程序需要运行在操作平台上也必须要经过JVM,能不能直接运行在操作系统上,因此,Java相对于C/C++这类语言,必将会花费更多的时间。
1 Java开发环境
- JRE(Java Runtime Environment):Java运行环境
- JDK (Java Development Kit):Java开发工具包
1.0 JDK
对于JDK来说,尽量使用稳定版或者长期支持版(LTS),详情见Oracle官网JDK下载地址。尽管下一个LTS的Java17都快要发布了,但是国内占用比例最大为JDK8。
1.1 关于Java的环境变量
添加JAVA_HOME
环境变量为JDK的存放或安装路径,再在Path
环境变量中添加%JAVA_HOME%\bin\
和%JAVA_HOME%\jre\bin\
。这里暂时没有配置到CLASSPATH
,到后面有需要时再去设置。
1.2 代码编辑器
- 微软开源轻量级的代码编辑器:VSCode
- JetBrains全家桶(收费)之一:IntelliJ IDEA
2 第一个程序
2.0 编写之前 - Java程序的生成与运行
Java在经过编写之后,就会使用到我们第一个命令javac
,我们用它来编译我们写好的Java源代码,通过它我们可以将Java的源代码——一个.java
文件,在没有编译错误的前提下,编译成一个能供JVM运行的字节码文件——一个.class
文件,然后再使用命令java
来让我们编译好的运行到JVM之中,当然希望这一切都可以顺利的进行,但是也有可能会出现有一些错误,将写在之后。
以上涉及到了两个命令
Javac
:Java编译命令javac <options> <source files> options:参数选项,具体选项后面在使用中再提及 source files:源文件路径
Java
:Java运行命令java [-options] class [args...] 执行上面编译好的.class文件,class为文件名,不需要加.class后缀 java [-options] -jar jarfile [args...] 执行一个jar包
2.1 Hello Word!
想必这是学习每一个编程语言都会编写的第一个程序吧!
Sample01.java
public class Sample01 { //Sample01为该文件唯一一个带public的类名
public static void main(String[] args) {
System.out.println("Hello Word!");
}
}
这个程序就将在终端中打印出Hello Word!
,但是也有可能会发生以下的错误,这是什么原因呢?
PS D:\OpenLab\JavaSE\Day01-20210112> javac .\Sample01.java
.\Sample01.java:1: 错误: 类Sample02是公共的, 应在名为 Sample02.java 的文件中声明
public class Sample02 {
^
1 个错误
原因:源代码的文件名必须与源代码中的唯一一个带public
的类名相同,如果不相同就会发生编译错误
2.2 常见错误类型
- 语法/编译错误:编译无法完成出现
Error
- 运行时错误:编译可以完成,运行会抛出异常(
Exception
)程序终止
3 基本数据类型与运算
3.0 标识符
标识符是用于对变量、常量、类、方法、接口定义的名称。
3.0.0 规则
- 标识符可以由数字、字母、下划线
_
、美元符$
组成 - 标识符不能以数字开头
- 不能是关键字
- 区分大小写
3.0.1 规范
- 大驼峰式(CamelCase),也称之为Pascal命名法,用于类名和接口名
- 小驼峰式(camelCase),用于变量名和方法名
- 常量命名:所有单词全部大写,单词之间用下划线
_
分隔开 - 包名命名:所有单词全部小写,单词之间用点
.
分隔开 - 非类文件名:所有单词全部小写,单词之间用下划线
_
和短横线-
分隔开
3.1 注释
- 单行注释
//This is a one-line comment.
- 多行注释
/* This is a multi-line comment. This is another comment line. */
- 文档注释
/** * This is a document comment. * It has information about the program. * As follow: * @author Fosyme */
注意:文档注释可以被解析成单独的文档,作为API使用
3.2 常量
直接出现而未被定义的量称之为常量,也叫字面量
- 整数字面量
- 小数字面量
- 字符字面量,被单引号
''
标识的一个字符 - 字符串字面量,被双引号
""
表示的若干个字符 - 布尔字面量
null
字面量
3.3 变量
变量值能够变化的量
- 变量存储在内存中程序所处进程的临时区中
- 变量的内存大小一旦生成无法改变
- 具有向下兼容性
- 该内存真实存在,拥有其可寻地址
3.4 数据类型
3.4.0 基本数据类型
- 整型
byte
: 1Byteshort
: 2Byteint
: 4Bytelong
: 8Byte
- 浮点型
float
: 4Bytedouble
: 8Byte
- 字符型
char
: 2Byte
- 布尔型
boolean
: 不确定在常量中,整型常量默认int类型,小数常量默认是double类型
布尔类型,如果是单一变量的话,在JVM中true被认为是1 false被认为是0 所以是4字节存
如果是布尔类型数组的话,在JVM中true和false被认为是byte类型 1字节
3.4.1 引用数据类型
主要是指对象,数据是在堆内存中存储,变量仅仅存放的是数据在堆内存中的地址
3.5 运算符
3.5.0 算术运算符
运算符 | 含义 | 备注 |
---|---|---|
+ | 加法 | 如果左右为字符串,则为连接符 |
- | 减法 | |
* | 乘法 | |
/ | 除法 | 如果运算数都为整数,结果就为整数 |
% | 取余 | |
a++ | 后置自增 | 先使用再加一 |
++a | 前置自增 | 先加一再使用 |
a-- | 后置自减 | 先使用再减一 |
--a | 前置自减 | 先减一再使用 |
3.5.1 赋值运算符
运算符 | 含义 | 备注 |
---|---|---|
= | 赋值 | 将右边的对应值赋值给左边 |
+= | 加赋值 | a += b; 等价于 a = a + b; |
-= | 减赋值 | a -= b; 等价于 a = a - b; |
*= | 乘赋值 | a *= b; 等价于 a = a * b; |
/= | 除赋值 | a /= b; 等价于 a = a / b; |
%= | 取余赋值 | a %= b; 等价于 a = a % b; |
3.5.2 比较运算符
运算的结果为布尔类型
运算符 | 含义 |
---|---|
> | 大于 |
< | 小于 |
>= | 大于等于 |
>= | 大于等于 |
!= | 不等于 |
3.5.3 逻辑和位运算符
运算的结果为布尔类型
运算符 | 含义 |
---|---|
&& | 短路与 |
|| | 短路或 |
! | 非,取反 |
& | 按位与 |
| | 按位或 |
^ | 异或 |
>> | 右移 |
<< | 左移 |
3.5.4 三目运算符
运算符 | 含义 |
---|---|
expression ? true result : false result | 如果expression 为真则返回true result ,反之,返回false result |
4 流程控制语句
4.0 if条件语句
4.0.0 单分支if
...
if (expression) {
statement;
...
}
...
4.0.1 双分支if-else
...
if (expression) {
statement1;
...
} else {
statement2;
...
}
...
4.0.2 多分支if-else-if
...
if (expression1) {
statement1;
...
} else if (expression2) {
statement2;
...
} else if (expression3) {
statement3;
...
} ... else {
statement;
}
...
4.1 switch分支语句
- 可传入
char
,byte
,short
,int
,String
或者枚举
类型的变量或常量 case
值的数据类型应相同- 匹配
case
就向下执行,直到遇到第一个break;
跳出switch
switch(var) {
case 1:
statement1;
break;
case 2:
statement2;
break;
case 3:
statement3;
break;
default:
statement;
break;
}
4.2 for循环语句
四要素
- 循环初始化
- 循环条件
- 循环体
- 循环后缀
for (1.initialization, 2.expression, 4.statement) {
3.statement_for;
...
}
先执行初始化,然后判断表达式,若真继续执行循环语句,然后执行循环后缀语句,然后判断表达式,循环;若表达式为假不再执行循环
4.3 while循环语句
while (expression) {
statement;
...
}
当表达式为真的时候,就执行下面的语句,然后判断表达式,循环
4.4 break、continue跳转语句
break
在循环语句中叫做终止语句,终止的是break
最近的一层循环continue
在循环语句中叫做跳过语句,跳过本次循环开启下一轮循环
4.5 编程练习
4.5.0 反转数字
通过对数字进行取余,逐次从右向左取出每一个数字,然后根据10进制的进制法,将各个相乘相加等到原数的反转数,如果反转数需要准确数值需要防止溢出(使用一个比原来精度高的数值类型)
import java.util.Scanner;
public class Demo23 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter a number:");
int num = input.nextInt();
int temp = num;
int renum = 0;
while (temp != 0) {
renum = renum * 10 + temp % 10;
temp /= 10;
}
if (num == renum) {
System.out.println("yes");
} else {
System.out.println("no");
}
}
}
4.5.1 最大公约数
方法一(穷举法):将两个数中的最小那个数作为开始,依次减一用于遍历,将两个数与遍历数进行取余,若两数都能够被整除,那这个数就是两个数的最大公约数。
import java.util.Scanner;
public class Demo33 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入两个数字:");
int num1 = input.nextInt();
int num2 = input.nextInt();
int min = num1 < num2 ? num1 : num2;
int gcd = 1;
for (int i = min; i > 0; i--) {
if (num1 % i == 0 && num2 % i == 0) {
gcd = i;
break;
}
}
System.out.println("最大公约数为:" + gcd);
}
}
方法二(辗转相除法):找出两个数中的最大最小值,然后将大值对小值取余,然后将余数作为小值,除数作为大值,循环取余,直至余数为0停止,其余数就为最大公约数。
import java.util.Scanner;
public class Demo33 {
public static void main(String[] args) {
int a = 1;
int b = 1;
int gcd = 1;
Scanner in = new Scanner(System.in);
try {
System.out.print("Please enter two integers: ");
a = in.nextInt();
b = in.nextInt();
} catch (Exception e) {
System.out.println("Illegal input!");
}
int max = Math.max(a, b);
int min = Math.min(a, b);
gcd = max % min;
while (min % gcd != 0) {
gcd = min % gcd;
min = gcd;
}
System.out.println("The gcd is " + gcd);
}
}
5 常用类
5.0 Math类
Math属于数学方面的一个工具类
常量
Modifier and Type | Field | Description |
---|---|---|
static double | E | 自然对数 |
static double | PI | 圆周率 |
取整方法
Modifier and Type | Method | Description |
---|---|---|
static double | ceil(double a) | 向上取整 |
static double | floor(double a) | 向下取整 |
static long | round(double a) | 四舍五入 |
三角函数
Modifier and Type | Method | Description |
---|---|---|
static double | sin(double a) | 正弦函数 |
static double | cos(double a) | 余弦函数 |
static double | tan(double a) | 正切函数 |
static double | toDegrees(double a) | 将弧度转角度 |
static double | toRadians(double angles) | 将角度转弧度 |
static double | asin(double a) | 反正弦函数 |
static double | acos(double a) | 反余弦函数 |
static double | atan(double a) | 反正切函数 |
指数函数
Modifier and Type | Method | Description |
---|---|---|
static double | pow(double a, double b) | 求a的b次幂 |
static double | sqrt(double a) | 求a的平方根 |
static double | cbrt(double a) | 求a的立方根 |
其他方法
Modifier and Type | Method | Description |
---|---|---|
static double | abs(double a) | 求a的绝对值 |
static double | hypot(double x, double y) | 返回 x 2 + y 2 \sqrt{x^2+y^2} x2+y2 |
static double | max(a,b) | 返回a和b之间的最大值 |
static double | min(a,b) | 返回a和b之间的最小值 |
static double | random() | 返回[0,1)之间的随机小数 |
5.1 Scanner类
与输入流有关的类
Modifier and Type | Method | Description |
---|---|---|
String | next() | 获取下一个字符串直到空格 |
String | nextLine() | 获取下一个字符串直到换行 |
int | nextInt() | 获取下一个整数 |
double | nextDouble() | |
boolean | nextBoolean() | |
float | nextFloat() |
5.2 Random类
用于产生随机事件
Modifier and Type | Method | Description |
---|---|---|
boolean | nextBoolean() | 随机产生布尔类型的值 |
double | nextDouble() | 随机生成0.0~1.0之间的小数 |
double | nextInt() | 随机生成一个整数0~232的整数 |
double | nextInt(n) | 随机生成一个整数[0, n)的整数 |
5.3 String类
String是一个关于字符串的类,生成后的String的对象不可以修改其内容与长度。
获取相关
Modifier and Type | Method | Description |
---|---|---|
char | charAt(int index) | 获取索引为index处的字符 |
int | indexOf(int ch) | 获取字符在字符串中第一次出现的索引,若不存在返回-1 |
int | lastIndexOf(int ch) | 获取字符在字符串中最后一次出现的索引,若不存在返回-1 |
int | indexOf(String str) | 获取字符串在该字符串中第一次出现的索引,,若不存在返回-1 |
int | lastIndexOf(String str) | 获字符串在该字符串中最后一次出现的索引,,若不存在返回-1 |
int | length() | 获取字符串的长度 |
String[] | split(String regex) | 将字符串按照给定regex正则表达式内容进行拆分 |
String | substring(int beginIndex) | 截取索引从beginIndex开始的子字符串 |
String | substring(int beginIndex, int endIndex) | 截取索引从beginIndex到endIndex(不包含)的子字符串 |
判断相关
Modifier and Type | Method | Description |
---|---|---|
int | compareTo(String anotherString) | 按照字典顺序比较两个字符串的大小 |
boolean | contains(String another) | 判断该字符串是否包含目标字符串 |
boolean | equals(String another) | 比较该字符串与目标字符串的内容是否相同 |
boolean | isEmpty() | 判断该字符串是否为空 |
boolean | startsWith(String prefix) | 判断该字符串是否以prefix开头 |
boolean | endsWith(String suix) | 判断该字符串是否以suix结尾 |
修改相关
Modifier and Type | Method | Description |
---|---|---|
String | toLowerCase() | 将字符串中的英文字母转化为小写 |
String | toUpperCase() | 将字符串中的英文字母转化为大写 |
String | trim() | 将字符串中两端的多余空格删除 |
String | replace(char oldCh,char newCh) | 将字符串中oldCh字符替换成newCh字符 |
5.4 Character类
Modifier and Type | Method | Description |
---|---|---|
static boolean | isDigit(char ch) | 判断字符是否是数字 |
static boolean | isLetter(char ch) | 判断字符是否是字母 |
static boolean | isLetterOrDigit(char ch) | 判断字符是否是数字或字母 |
static boolean | isLowerCase(char ch) | 判断是否是小写字母 |
static boolean | isUpperCase(char ch) | 判断是否是大写字母 |
static boolean | isSpaceChar(char ch) | 判断是否空白字母 |
5.5 编程练习
5.5.0 检测子串
让循环遍历长字符串,首先在长字符串找寻是否与短字符串头字符相同的字符,然后判断短字符串后面的字符是与对应的位置的字符相同,如果相同就判断为子串,如果不相同就继续判断,直至短字符串被遍历完。
public class Demo60 {
public static void main(String[] args) {
String s1 = "My name is Hello";
String s2 = "Heit";
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) == s2.charAt(0)) {
int k = 1;
for (int j = i + 1; k < s2.length(); j++) {
if (s2.charAt(k) != s1.charAt(j)) {
break;
}
}
if (k = s2.length()) {
System.out.println("true");
return;
}
}
}
System.out.println("false");
}
}
5.5.1 两个字符串中最长的公共子串
将两个字符串中短字符串的最长子串(就是其本身)开始,判断是否为长字符串的子串,如果不是,就子串长度就逐次减一,去判断是否为长字符串的子串。
public class Test01 {
public static void main(String[] args) {
String s1 = "abc123021";
String s2 = "dbc1321";
for (int i = s2.length(); i > 0; i--) {
for (int j = 0; j <= s2.length() - i; j++) {
if (s1.contains(s2.substring(j, i + j))) {
System.out.println(s2.substring(j, i + j));
return;
}
}
}
}
5.5.2 最长的共同前缀
需要找寻两个字符串最长共同前缀,让短字符串的第一个字符与长字符串第一个字符进行比较,如果相等,就将索引逐次加一,直到两字符不相等为止,最后从头开始到不相等字符的索引的字符串就是两字符串的最长共同前缀。
import java.util.Scanner;
public class Demo66 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter s1:");
String s1 = in.nextLine();
System.out.print("Enter s2:");
String s2 = in.nextLine();
int i = 0;
while (i < s2.length()) {
if (s1.charAt(i) != s2.charAt(i)) {
break;
}
i++;
}
System.out.println(s2.substring(0, i));
}
}
更多内容: JavaSE学习笔记2 | JavaSE学习笔记3