前言
学习一门语言,快速入门是给我们增加学习信心的法门。如果门槛都跨不进去,学习就是不可能的事。学习能力实际上体现的是一个人跳出舒适圈的意愿程度。
简介
Java程序必须运行在JVM之上,我们必须安装jdk,此时我们实验的环境是jdk13。
程序基础
java程序基本结构
Java是面向对象的语言,一个程序的基本单位就是class
。
类名要求:
- 类名必须以英文字母开头,后接字母,数字和下划线的组合
- 习惯以大写字母开头
在class内部,可以定义若干方法
(method)。方法名也有命名规则,命名和class一样,但是首字母小写。
Java入口程序规定的方法必须是静态方法,方法名必须为main,括号内的参数必须是String数组。
在方法内部,语句才是真正的执行代码。Java的每一行语句必须以分号结束
举例:
1 | public class Hello { //类名是Hello |
变量和数据类型
变量
- 在Java中,变量必须先定义后使用,在定义变量的时候,可以给它一个初始值。不写初始值,就相当于给它指定了默认值。默认值总是0。
- 变量的一个重要特点是可以重新赋值。
- 变量不但可以重新赋值,还可以赋值给其他变量。
数据类型
- 基本数据类型
基本数据类型是CPU可以直接进行运算的类型。Java定义了以下几种基本数据类型:
- 整数类型:byte,short,int,long
- 浮点数类型:float,double
- 字符类型:char
- char类型使用单引号
'
,且仅有一个字符
- char类型使用单引号
- 布尔类型:boolean
- 常量
- 定义变量的时候,如果加上final修饰符,这个变量就变成了常量。
- 常量在定义时进行初始化后就不可再次赋值,再次赋值会导致编译错误。
- 常量的作用是用有意义的变量名来避免魔术数字(Magic number)。
- 常量名通常全部大写。
- var关键字
- 如果想省略变量类型,可以使用var关键字。
举例:
1 | StringBuilder sb = new StringBuilder(); |
等价于
1 | var sb = new StringBuilder(); |
数学运算(略)
不想把重点放在数学计算上面,主要是需要学习程序的逻辑。
布尔运算
主要学习短路运算
和三元运算符
。
- 短路运算
短路运算的原理就是,如果A
是true,那么不会判断B
是不是true,A&&B
的结果直接返回true。 - 三元运算符
原理是:如果b
是true,b?x:y
返回的值是x,否则返回y。其实就是if-else
的简化写法。
字符和字符串
字符和字符串的区别是什么?
- 字符是
char
,它是基本数据类型。- 字符只表示一个字符,用
'
引起来。
- 字符只表示一个字符,用
- 字符串是
String
,它是引用类型。- 字符串可以表示0~n个字符,用
"
引起来。 - 如果是多行字符串,可以用
"""
引起来,避免写换行符。 - 多个字符串可以使用
+
拼接。
- 字符串可以表示0~n个字符,用
附加知识点:空值null
null
其实就是指不存在的东西。
- 把null赋值给一个变量,那么这个变量是null。
- 不给变量赋初值,这个变量也是null。
- 把一个null变量赋值给另一个变量,这另一个变量也是null。
- 但是空字符串不等于null。
打个绕口的比喻:我把没有
给你,你也是没有
。我拿一张白纸
给你,那么你也有了一张白纸
,尽管纸上什么也没有,但你不是没有
。没有
这个东西,不管怎么传递,还是没有
,不会无中生有。
举例:1
2
3
4String s1 = null; // s1是null
String s2; // 没有赋初值,s2也是null
String s3 = s1; // s3也是null
String s4 = ""; // s4指向空字符串,不是null
数组类型
定义一个数组类型的变量,使用数组类型类型[]
,例如,int[]
。和单个基本类型变量不同,数组变量初始化必须使用new int[5]表示创建一个可容纳5个int元素的数组。
Java的数组有几个特点:
- 数组所有元素初始化为默认值,整型都是0,浮点型是0.0,布尔型是false;
- 数组一旦创建后,大小就不可改变。
- 要访问数组中的某一个元素,需要使用索引。数组索引从0开始,例如,5个元素的数组,索引范围是0~4。
- 可以修改数组中的某一个元素,使用赋值语句,例如,ns[1] = 79;。
- 可以用数组变量.length获取数组大小。
- 数组是引用类型,在使用索引访问数组元素时,如果索引超出范围,运行时将报错。
- 也可以在定义数组时直接指定初始化的元素,这样就不必写出数组大小,而是由编译器自动推算数组大小。
举例:
1 | public class Main { |
引申学习:字符串数组
1 | public class Main { |
这段代码的运行结果是"XYZ"
,说明的是java里面赋值是一种类似指针的概念。names[1]的值指向了s这个变量,之后又把"cat"
指向names[1]这个变量。只要指向关系没有改变,变量的 值就不会发生变化。
流程控制
输入和输出
输出
的方法比输入
的方法简单。先看输出。
- 输出
println
println
意思是printline
,它会帮我们自动输出换行符。print
普通输出,不会自动输出换行符。printf
f
的意思是format
,就是格式化输出的意思。这里和以前学过的C语言的printf用法就差不多的。不细说,需要用的时候查资料。
- 输入
首先是需要引入java.util.Scanner
这个java模块。
用法:
- 创建Scanner对象。
- 打印输入提示信息:提示用户需要输入的数据类型是什么。
- 用户输入信息:可能是字符串或者整数。
- 读取用户输入的信息并获取字符串或者整数。
举例: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); // 格式化输出
}
}if判断
逻辑很简单,如果……,就……;否则,就……。
通常用到的就是这样的逻辑判断。关键点在于判断条件的设置方法。
这里有个特殊的用法,判断引用类型(比如字符串String
、数组
就是引用类型)的变量是否相等,要使用equals()
方法。
举例:运行结果:1
2
3
4
5
6
7
8
9
10
11
12
13public class Main {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "HELLO".toLowerCase();
System.out.println(s1);
System.out.println(s2);
if (s1.equals(s2)) {
System.out.println("s1 equals s2");
} else {
System.out.println("s1 not equals s2");
}
}
}
引申学习:.toLowerCase()
是String的一个方法,可以将字符串内容全部转换为小写字符。
switch多重选择
java13之后使用的语法和以前版本不同,我分成了老语法和新语法。人要与时俱进,老语法了解一下,要熟练应用新语法。
据我有限的知识储备,老语法和C语言中的switch用法差不多,和VHDL语法也差不多(还是学过VHDL语法的一点皮毛~),看来编程语法具有许多共通性。
- 老语法
switch语句里面的每一个case都要搭配break使用。
举例:switch语句还可以匹配字符串。字符串匹配时,是比较“内容相等”。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class Main {
public static void main(String[] args) {
int option = 99;
switch (option) {
case 1:
System.out.println("Selected 1");
break;
case 2:
System.out.println("Selected 2");
break;
case 3:
System.out.println("Selected 3");
break;
default:
System.out.println("Not selected");
break;
}
}
}
举例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class Main {
public static void main(String[] args) {
String fruit = "apple";
switch (fruit) {
case "apple":
System.out.println("Selected apple");
break;
case "pear":
System.out.println("Selected pear");
break;
case "mango":
System.out.println("Selected mango");
break;
default:
System.out.println("No fruit selected");
break;
}
}
} - 新语法
新的语法简洁许多,不用担心忘记写break。并且case里面可以直接使用yield
返回结果(python语法里面也有yield
的用法)。
举例:运行结果:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public class Main {
public static void main(String[] args) {
String fruit = "orange";
int opt = switch (fruit) {
case "apple" -> 1;
case "pear", "mango" -> 2;
default -> {
int code = fruit.hashCode(); //对字符串做hash
System.out.println(code); //code的值
yield code; // switch语句返回值
}
};
System.out.println("opt = " + opt); //yield返回的值就赋值给了opt
}
}
引申学习:.hashCode()
是String的一个方法,表示对字符串做hash。
while循环和do while循环
这和C语言中的概念也是差不多的,不细说。
while循环和do while循环的本质区别就是:
- while循环先判断条件,再循环。循环体可能不执行。
- do while循环先循环再判断。循环体至少执行1次。
初高中的时候,数学老师讲过的那两个拗口的中文解释:当型循环
和直到型循环
分别对应的就是while循环
和do while循环
。
for循环
原来学C语言的时候,把这个for循环是搞昏了的,计数器到底怎么算,一直没搞清。主要是老师讲解的时候,注入了太多数学元素,而我对数字不太感冒,形不成感性认知,也就理解不清楚。现在站在一个稍微宏观的视角来理解,似乎也不难。
以这个例子(对1到100进行求和)来理解:
1 | public class Main { |
运行结果:
for循环部分,其实就是限定这个循环体的循环次数。从i=1开始,先判断i是否满足条件i<=100,如果满足,就进入循环体,循环结束后,计数器加1。继续判断现在的i是否满足条件i<=100,如果满足,就进入循环体……
发现了没有,我描述中的重复部分,就是在执行循环。这就是编程的伟大之处,它给我们节省不少口水和文字。
- 特殊用法
for each
这是java中的一个特殊用法,用来遍历数组。
举例:运行结果:1
2
3
4
5
6
7
8public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int n : ns) {
System.out.println(n);
}
}
}
这里的for (int n : ns)
意思就是,遍历数组ns中的每一个元素n。但是,for each循环无法指定遍历顺序,也无法获取数组的索引。
break和continue
在C语言和VHDL语言中,都学过这两个用法:break
、continue
。可以用在while循环和for循环中。break
就是戛然而止,就像坐热气球突然把气球炸了。而continue
就像刹车,拉手刹之后,车还会滑行一段。
数组操作
遍历数组
用for循环和for each循环可以实现数组的遍历。
- for循环遍历数组
举例:运行结果:1
2
3
4
5
6
7
8
9public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int i=0; i<ns.length; i++) {
int n = ns[i];
System.out.println(n);
}
}
} - for each循环遍历数组
前面学习for each循环的时候了解过,不赘述于此。 - 打印数组元素的妙方
Arrays.toString()
我们可以直接使用Arrays.toString()
这个方法将数组里面的每个元素打印出来,不必使用循环遍历数组。前提是我们要事先引入模块java.util.Arrays
才可以使用这个方法。
举例:运行结果:1
2
3
4
5
6
7
8import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 1, 2, 3, 5, 8 };
System.out.println(Arrays.toString(ns));
}
}数组排序
冒泡法可以对数组排序,但是鉴于本人对于数字的想象力有限,就不和冒泡法死磕了。java内置了排序方法Arrays.sort()
可以帮助我们排序,前提也是要导入模块java.util.Arrays
。
举例:运行结果:1
2
3
4
5
6
7
8
9import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] ns = { 28, 12, 89, 73, 65, 18, 96, 50, 8, 36 };
Arrays.sort(ns);
System.out.println(Arrays.toString(ns));
}
}
对数组排序实际上修改了数组本身。多维数组
学会魔方之后,这个问题好像没有那么难了。一维数组的元素就相当于是一个方块,二维数组的元素就是一层魔方,三维数组的元素就是一整个魔方。这么说简单一点,一维数组的单位是块,二维数组的单位是层,三维数组的单位是个。
- 二维数组
举例:运行结果:1
2
3
4
5
6
7
8
9
10public class Main {
public static void main(String[] args) {
int[][] ns = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
};
System.out.println(ns.length); // 3
}
} - 三维数组
略……命令行参数
这个命令行参数就是我们在命令行执行java程序时加的参数。
举例:我们到命令行,先编译这个java文件。1
2
3
4
5
6
7
8
9
10public class PrintArgs {
public static void main(String[] args) {
for (String arg : args) {
if ("-version".equals(arg)) {
System.out.println("v 1.0"); //这句代码的意思是如果用户输入的参数是-version,就打印输出v 1.0
break;
}
}
}
}接下来执行程序时带上参数1
javac .\PrintArgs.java
-version
:1
2PS F:\java学习\HelloWorld\src> java PrintArgs -version
v 1.0总结
快速入门到这里就完成了。把知识先储备在这儿,用的时候不至于陌生。