准备

JRE 与 JDK

  • JRE(Java Runtime Environment Java 运行环境)
    • 包括 JVM 和 Java 核心类库,安装后可运行 Java 程序,但无法开发。
  • JDK(Java Development Kit, Java 开发工具包)
    • 包括 JRE 和 Java 开发工具,可用于开发和运行 Java 程序

      版本说明

      对于 Oracle JDK ,1.8.0_202 版本后的更高版本在生产环境中使用将需要进行付费。

      安装

  1. 登录 Oracle 官网下载 JDK 1.8.0_202。
  2. 按照默认路径(推荐)进行安装。
  3. 使用 cmd 或其他控制台输入 java 验证。

Win 10 环境变量配置

基于 Windows 10 专业版 21H2 Windows 环境变量变量名不区分大小写 我们强烈不推荐在系统环境变量中设置classpath,那样会污染整个系统环境。在启动JVM时设置classpath才是推荐的做法。—— 引自廖雪峰

  1. win + R输入sysdm.cpl打开系统高级设置 -> 环境变量。(或直接点击 Windows 设置按钮 -> 系统 -> 关于 -> 相关设置 -> 高级系统设置)
  2. 系统变量 -> 新建变量名 JAVA_HOME,复制粘贴 JDK 安装绝对路径,如C:\Program Files\Java\jdk1.8.0_202
  3. 系统变量 -> Path -> 编辑 -> 新建,环境变量分别为 %JAVA_HOME%\bin%JAVA_HOME%\jre\bin
  4. 从 JDK 1.5 开始 CLASSPATH 默认是当前路径,不用再配置。如若需要,则同设置JAVA_HOME,新建变量名CLASSPATH,值为.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar
  5. 使用cmd或其他控制台程序,输入javac ,java -version进行验证。

JAVA_HOME,PATH,CLASSPATH 说明

待补充

入门

第一个 Java 程序

  1. // 记事本编写,保存为 HelloWorld.java
  2. public class HelloWorld{
  3. public static void main(String[] args){
  4. System.out.println("HelloWorld");
  5. }
  6. }
  7. # 使用cmd 进入 HelloWorld .java 的保存目录执行
  8. C:\Users\admin>javac HelloWorld.java
  9. C:\Users\admin>java HelloWorld

注意事项

  • 源文件以 .java 为扩展名。
  • 程序执行入口main() 方法。
  • 严格区分大小写。
  • 每条语句以英文分号 ; 结束。
  • 源文件中有且仅有一个 public class 并且和源文件名保持一致。其他 class 个数、名字不限。javac 公共类名 会同时将其他类一起编译。

    Java 程序执行过程

  • .java 文件 —(javac)编译器编译—> *.class 字节码文件 —(java) JVM 执行 —> 结果

关键字和保留字

关键字:被 Java 语言赋予了特殊含义,用做专门用途的字符串(单词)

Java 保留字:现有 Java 版本尚未使用,但以后版本可能会作为关键字使用。

常见转义字符

  • \t 制表符
  • \n 换行
  • \ \
  • ‘’ 双引号
  • ‘ 单引号
  • \r 回车
    • IDEA 中结果为回到本行首位并用 \r 后的内容完全覆盖前面的内容(无论 \r 后的内容是否比前面的长)
    • 控制台结果为回到本行首位并用 \r 后的内容按长度覆盖前面的内容(若长度小于被覆盖内容,被覆盖内容仍然可见后面部分)

注释

  • 单行注释 //
  • 多行注释 /* */
  • 文档注释 /** */

Java 代码规范

  • 类、方法的注释,以 javadoc(文档注释) 形式书写.
  • 使用 tab 缩进(四个空格)。
  • 符号两边各加一个空格。
  • 编码使用 UTF-8。
  • 代码编写使用行尾风格(推荐)或次行风格。

命名规则

  1. 由数字、英文字母、下划线_ 或 $ 组成
  2. 不能使用关键字和保留字,但能包含。
  3. 严格区分大小写,长度无限制,不能有空格。

命名规范

  • 包名:多单词组成时所有字母小写,推荐域名反转,如 com.google.test
  • 类名、接口名:多单词组成时,大驼峰(单词首字母大写),如 AaaBbbCcc
  • 变量名、方法名:多单词组成时,小驼峰(首字母小写,其他同大驼峰)。
  • 常量名:全大写,多单词组成时,下划线做分隔。

    变量

简介 可以看作是由内存提供的一个存放数据的容器。一般由数据类型、名称、值构成,根据变量名可以访问到变量(值)。

变量的声明与使用

  1. // 声明并赋值(推荐)
  2. int a = 1;
  3. // 或先声明,再赋值
  4. int b;
  5. b = 1;
  6. // 再使用
  7. System.out.println(a);
  8. System.out.println(b);

变量声明可以同类型,但不能同名。
声明和定义是有区别的,但在 Java 中,并没有像 C/C++ 那样真正的分离声明和定义,因此不必过于纠结。

Java API 文档

API(application programming interface,应用程序编程接口),是 Java 提供的基本编程接口,提供了大量的基础类与方法。

官方提供相应的 API 文档为开发者介绍如何使用这些类和方法。

数据类型

每一种数据都定义了明确的数据类型,并在内存中分配了不同大小的内存空间。

Java 的数据类型有两大类:基本数据类型和应用数据类型。

Java 的数据类型有固定的范围和字段长度(因为 JVM),不受物理机系统的影响。

编码表

ASCII 编码表

Unicode 编码表

Java SE 基础 - 图1

UTF-8 编码表

Java SE 基础 - 图2

GBK 编码表

GBK 2312

big5 码

Java SE 基础 - 图3

基本数据类型

数值型

  • 整型:byte[1],shor[2],int[4],long[8]
  • 浮点型:float[4],double[8]

字符型 char[2]

布尔型 boolean[1]

整型使用细节

  • 默认为 int 若使用 long 需要在数值后加 lL

Java SE 基础 - 图4

浮点型使用细节

  • 浮点数在机器中存放形式,浮点数=符号位+指数位+尾数位。尾数部分可能丢失,造成精度损失(小数都是近似值)
  • 默认为 double ,若使用 float 需要在数值后加 fF
  • 科学计数法 3.14*10² <=> 3.14e23.14e-2 负二次方,e 大小写等价。
  • 判断浮点数和浮点数除法的结果是否相等:二者之差的绝对值是否在要求精度范围内。

Java SE 基础 - 图5

字符型使用细节

  • 两个单引号括起来一个字符,可以使用转义字符 \ 转为特殊字符常量(如换行符\n
  • 本质是一个整数,可以进行运算。
  • 输出是与 Unicode 码对应的字符。因此可以按照 Unicode 编码赋值输出对应字符。

布尔型使用细节

  • 占一个字节,只允许 true false
  • 适用于逻辑运算。

数据类型转换

自动类型转换 按照精度范围,小范围自动转为大范围。

  • char < int < long < float < double
  • byte < short < int < long < float < double

细节

  • 多类型数据混合运算,系统自动将所有数据转换成精度范围最大的,再计算。结果类型范围为最大的。
  • 大精度 —> 小精度,报错。反之,自动转换。
  • byte short 二者不会与 char 自动转换。
  • byte short char 可以进行数值计算,会先转为 int 型。
  • boolean 不参与转换

强制类型转换

  • 大范围 —> 小范围使用() ,可能造成精度降低或溢出。
  • 只针对最近的操作数有效,使用小括号提升优先级。
  • char 不能保存 int 变量,需强转。

引用数据类型

  • 类(class)
  • 接口(interface)
  • 数组([])

基本数据类型和 String 类型转换

  • 基 —> String 使用 + 拼接 "" 即可。
  • String —> 基,使用基本类型包装类的 parseXxx() 方法。

String 常见方法(下标起始 0)

图源 String类的20种常见方法Jacky_Cmd-CSDN博客string类的20种常见方法

image.png

image.png

运算符

图源菜鸟教程

用于数据的运算、赋值和比较等。

一般包括

  • 算术运算符
  • 赋值运算符
  • 关系运算符
  • 逻辑运算符
  • 位运算符
  • 三元(目)运算符

算数运算符

image.png

赋值运算符

image.png

关系运算符

运算结果为 boolean
image.png

逻辑运算符

运算结果为 boolean

image.png

位运算符

image.png

三元运算符

表达式 ? 布尔值 : 布尔值

instanceof 运算符

检查该对象是否是一个特定类型

运算符优先级

image.png

流程控制

三大流程控制语句

  • 顺序控制
  • 分支控制
  • 循环控制

分支控制

单分支 if

双分支 if else

多分支 if ... else if ... else

分支结构可以嵌套

switch 分支结构

  1. switch(表达式){
  2. case 常量1
  3. 语句块1;
  4. break;
  5. ...
  6. default: // 可选
  7. 语句块;
  8. break
  9. }
  • 如果不同常量执行的语句块相同,则写为

    1. case 常量1
    2. case 常量2:
    3. 语句块;
    4. break;
  • 表达式可以是 byte short int char enum。从 Java SE 7 开始支持 Stringcase 标签必须为字符串常量或字面量。

循环控制

for 循环 for(循环变量初始化;循环条件;循环变量迭代){...}

  • 循环变量可多个一起初始化,使用 , 隔开,循环条件也一样。
  • 多重 for 循环,当最内层 for 循环执行完毕,才执行外层循环。

while 循环 while(条件){...}

  • 条件为 true 将继续执行循环体。

do…while() do{...}while(条件)

  • 至少执行一次 do 中的循环体,然后再判断条件,为 true 则继续执行循环体。

break、continue 和 return

return 使用在方法,表示跳出所在的方法。

breakcontinue 都是终止语句块的继续执行,在此之前的语句都会执行,一般用于跳出语句块(如循环),不同之处在于:

  • break 完全不会再执行该语句块。
  • continue 结束本次循环,执行下一次循环。
  1. for (int i= 1; i<10;i++){
  2. System.out.println("a"); // 必被执行
  3. if (i == 1) break; // 一旦触发,整个循环结束
  4. System.out.println(i);
  5. }
  6. for (int j= 1; j<10;j++){
  7. System.out.println("a"); // 必被执行
  8. if (j == 1) continue; // 一旦触发,j = 1 的循环结束,执行 j = 2 的
  9. System.out.println(i);
  10. }

数组

数组基础

可以存放多个同一类型的数据。数组也是一种数据类型,是引用类型。

定义数组

  1. // 方式一 动态初始化
  2. elemType[] name = new elemType[num];// num 表示数组大小(元素个数)
  3. // 方式二 动态初始化
  4. elemType[] name;
  5. name = new elemType[num]
  6. // 方式三 静态初始化
  7. elemType[] name = {a,b,...}; // 元素个数即为数组大小

访问数组 name[2]

  • 数组下标从 0 开始.
  • 访问全部元素使用 for/for each

    注意

  • 数组是相同数据类型元素的集合,数组元素可以是任何数据类型。

  • 创建数组后未赋值会有默认值,整型为 0,浮点型 0.0,字符型 \u0000,布尔型 false,引用类型 null。
  • 超出数组范围会发生越界异常。

    数组赋值机制

    以下问题的结果都是要求以原始变量名

将一个数组赋值另一个数组

默认情况下是引用传递,赋的值是地址。

  1. int[] a = {1,2,3};
  2. int[] b = a;
  3. b[0] = 99; // 此时,a 数组也变成 99,2,3

数组拷贝

解决上述问题,利用 for/for each 逐个赋值。

  1. int count = 0;
  2. for(int temp : a){
  3. b[count++] = temp;
  4. }

image.png

数组反转

将元素内容反转,两种思路:

  1. 首尾元素两两交换,进行 length/2 向下取整次。(临时变量)
  2. 或是逆序赋值。(临时数组)

    数组扩容

    动态给数组添加元素,思路:数组容量已满,新建长度加 1 的数组,原始数组遍历赋值给新数组,并将新添加元素加入新数组末尾。

    初见排序和查找

    外部排序 数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。包括(合并排序法和直接合并排序法)
    内部排序 指将需要处理的所有数据都加载到内部存储器中进行排序。包括(交换式排序法、选择式排序法和插入式排序法)

    冒泡排序

    从前往后依次两两比较,后者大于前者则交换位置。一共进行 n-1 轮比较,每轮比较 n - i
    bubbleSort.gif

    二分查找

    前提 元素有序且使用顺序存储结构
    序列为基数,首尾索引相加/2 (无论从 0 还是 1 开始计数)。
    序列为偶数,首尾索引相加/2 再向下取整 (无论从 0 还是 1 开始计数)。

    二维数组

    可以理解为数组元素是数组,且行列个数不强制相等。
    形式为 elemType[][] name;可以理解为行列,访问都是指定位置如 elemType[1][1]
    除此之外还有 elemType name[][];elemType []name[];

    使用方式1——动态初始化

    1. // elemType[][] arrName = new elemType[大小][大小];
    2. int[][] arr1 = new int[2][3];
    同一位数组,索引是从 0 开始,声明时的仅为大小(个数)

    使用方式2——动态初始化

    1. //先声明,再定义(开辟空间)
    2. int[][] arr2;
    3. arr2 = new int[2][3];

    使用方式3——动态初始化-列数不确定

    image.png
    1. //创建二维数组,一个有 3 个一维数组
    2. //虽然看起来有new,但每个一维数组还没有开辟空间
    3. //打印结果为 null 而非一个地址
    4. int[][] arr3 = new int[3][];
    5. // 赋值
    6. for (int i = 0; i < arr2.length; i++) {
    7. // 给每行的一维数组开空间,开多少取决上图
    8. arr2[i] = new int[i+1];
    9. // 指定位置赋值
    10. for (int j = 0; j < arr2[i].length; j++) {
    11. arr2[i][j]=i+1;
    12. }
    13. }
    14. // 打印
    15. for (int[] arr:arr2) {
    16. for (int i = 0; i < arr.length; i++) {
    17. System.out.print(arr[i] + "\t");
    18. }
    19. System.out.println();
    20. }

    使用方式4——静态初始化

    1. elemType[][] arr4 = {
    2. {elem1,...},
    3. ...,
    4. {elem1,...}
    5. };
    上述只是为了通过“表格行列”这一概念,更好理解二维数组,进行了格式化。