JavaSE基础

发布时间 2023-08-09 11:35:48作者: Rover20230226

一、Java背景

目标

  • JDK、JRE、JVM
  • 跨平台原理

(一)JDK、JRE、JVM

JDK ( Java Development Kit):是 Java 开发工具包,是整个 Java 的核心,包括了 Java 运行环境 JRE、Java 工具和 Java 基础类库。

简化:开发工具包 + 整个核心。含环境、工具和基础类库

JRE( Java Runtime Environment):是 Java 的运行环境,包含 JVM 标准实现及 Java 核心类库。

简化:运行环境。标准实现、核心类库

JVM( Java Virtual Machine):是 Java 虚拟机,是整个 Java 实现跨平台的最核心的部分,能够运行以 Java 语言写作的软件程序。所有的 Java 程序会首先被编译为 .class 的类文件,这种类文件可以在虚拟机上执行。

简化:虚拟机,跨平台核心,运行程序。先转 .class类文件 -> 能在虚拟机运行

开发 Java 程序,需要三个步骤: 编写代码,编译代码,运行代码

(二)跨平台原理

一次编译,处处执行

跨平台的不是 JVM ,是 Java语言

二、基础语法

目标

注释、标识符、关键字、数据类型、变量与常量、运算符、类型转换、键盘录入、分支语句、循环语句、数组、二维数组、方法

思路

基础常识

(一)注释

  1. 概念:对代码的解释和说明

  2. 格式:

    (1)单行注释:// 注释信息

    (2)多行注释:/* 注释信息 */

    (3)文档注释:/** 注释信息 */

(二)标识符

  1. 概念:起名字时使用的字符序列

  2. 命名规则:

    (1)字母、数字、下划线( _ )、$

    (2)不能使用数字开头

    (3)不能使用 Java 的关键字

    (4)区分大小写

  3. 命名规范:

    (1)类、接口:(大驼峰命名)

    • 每一个单词的首字母都采用大写字母

    (2)变量、方法:(小驼峰命名)

    • 第一个单词以小写字母开始,第二个及以后的每个单词的首字母大写

    (3)常量:

    • 字母全部大写

(三)关键字

  1. 概念:java中有特殊意义的词
  2. 特点:
    • 完全是小写的字母
    • 常见的开发软件中会有特殊颜色标识
  3. 特殊:main不是关键字,但是是一个会被 JVM 识别的特殊的单词

(四)数据类型

  1. 计算机存储单元

    • 位(bit) 又称之为 比特位
    • 字节(Byte)是计算机数据存储的最小单位
  2. 数据类型(默认:整数 int 小数 double)

    1. 基本数据类型

      1. 数值型

        1. 整数:byte, short, int, long
        2. 浮点数:float, double
        3. 字符:char
      2. 非数值型

        布尔:boolean

    2. 引用数据类型

      1. :class
      2. 接口:interface
      3. 数组:[ ]
  3. 默认值

    • 整型数组默认值都是0
    • 浮点数组 0.0
    • 布尔类型 false
    • 字符char 空格
    • 所有的引用类型数组默认值都是 null

(五)变量与常量

  1. 变量
    1. 概念:变量就是内存中可以发生改变的量。
    2. 定义格式:数据类型 变量名 = 初始值;
    3. 注意事项:
      1. 变量使用不能超过作用域的范围。
        【作用域】:从定义变量的一行开始,一直到直接所属的大括号结束为止。
      2. 可以通过一个语句来创建多个变量,但是一般情况不推荐这么写。
  2. 常量
    1. 概念:在程序运行过程中固定不变的量。
    2. 定义格式:final 数据类型 变量名 = 常量值;

(六)运算符

  1. 算术运算符:+ - * / % ++ --

    +
    在输出语句中,+连接符的前方,如果有字符串参与,那就不是加法,是字符串拼接,并且拼接后的结果仍是字符串。
    倘若需要在字符串后进行加法运算,则需要在两侧加上括号
    /
    多个整数相除,如果要想得到小数结果,必须得有一个小数参与运算
    
  2. 赋值运算符:= += -= *= /= %= 扩展赋值运算符底层自带强转功能

  3. 比较(关系)运算符:== < > <= >= !=

  4. 逻辑运算符:&& || ! ^ & |

  5. 三目运算符:数据类型 变量名= 比较表达式 ? 表达式1 : 表达式2;

    面试题1⭐
    int num1 = 10;
    int num2 = 20;
    int sum = (num1++) + (--num1) + (num2++) + (num2*10);
    System.out.println(sum);
    // 10 + (11 - 1) + 20 + (21 * 10) = 250
    

(七)类型转换

概念:把一种数据类型直接赋值给另外一种数据类型称为数据类型的转换。

  1. 隐式类型转换

    1. 概念:又叫做自动类型转换,系统自动把小类型转为大类型。

    2. 数据范围

      byte -> short -> int -> long -> float -> double

      ​ char ↑

    3. 定义 float 类型时必须在数字后面跟上 F 或者 f

  2. 强制类型转换

    1. 概念:大的数据转为小数据类,系统不能自动完成。
    2. 格式:小类型 变量名 = (小类型)大类型数据变量
    3. 注意:应该尽量避免出现强制转型,因为会产生精度损失,数据溢出。

(八)键盘录入

三个步骤:导包、创建对象、接收数据

// 导包的动作必须出现在类定义的上面
import java.util.Scanner;
//只有 sc 是变量名,可以变,其他的都不允许变
Scanner sc = new Scanner(System.in);
// 只有 i 是变量名,可以变,其他的都不允许变
int i = sc.nextInt();
练习题?
键盘录入一个整数,判断这个数在[1,10] 并且还得是一个奇数
如果符合要求 输出 符合  否则输出 不符合
public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.print("请输入一个数:");
    int i = sc.nextInt();
    if (i >= 1 && i <= 10 && (i % 2 == 1)) {
        System.out.println("符合");
    } else {
        System.out.println("不符合");
    }
}

(九)分支语句

  1. if 语句

    1. 格式 1:

      if (比较表达式) {
      	语句体;
      }
      
    2. 格式 2:

      if (比较表达式1) {
      	语句体1;
      }else {
      	语句体2;
      }
      
    3. 格式 3:

      if (比较表达式1) {
      	语句体1;
      } else if (比较表达式2) {
      	语句体2;
      } else if (比较表达式3){
      	语句体3;
      } else {
      	语句体n;
      }
      
  2. switch 语句

    switch (普通表达式) {
    	case 值1:
    		语句体1;
    		break;
    	case 值2:
    		语句体2;
    		break;
    	case 值3:
    		语句体3;
    		break;
    	...
    	default:
    		语句体n+1;
    		break; 
    }
    // 最后一个break语句可以省略,但是强烈推荐不要省略
    

    注意:

    1. 只能匹配byte short char int String 枚举
    2. default 必须存在
    3. 如果不加 break 就会出现case 穿透
  3. if 和 switch 选择问题

    如果表达式符合switch的条件,并且分支超过三个以上,这时应该用switch

(十)循环语句

  1. for 语句

    for (初始化语句; 比较表达式; 步进语句) {
    	循环体;
    }
    
    // 1.初始化语句  表示本次循环从第几次开始
    // 2.比较语句  表示本次循环到第几次结束
    // 3.步进语句  表示每循环一次,循环变量变化多少
    
    // 循环流程
        // 1.先执行初始化语句,并且只执行一次
        // 2.执行比较语句,如果为true则执行循环体
        // 3.执行步进语句
    
    // 作用域有大小,大的作用域无法访问小的作用域内的变量
    // 反过来,小的作用域可以访问大的作用域的变量
    
  2. while 语句

    while (比较表达式) {
    	循环体;
    }
    
    执行流程
    	看判断表达式的结果,如果为false循环结束,如果为true则执行循环体。
    	循环体执行完后继续看判断表达式的结果以此类推
    	
    // for 和 while 的选择性问题
    // 明确知道循环次数的时候,毫不犹豫选择 for
    // 不知道循环次数使用 while 循环
    
  3. do...while 语句

    do {
    	循环体;
    } while (比较表达式);
    
    执行流程
    	先执行循环体,然后看判断表达式的结果。如果为true则继续执行循环体
    	如果判断表达式的结果为false则循环结束,如此反复。
    
  4. for 与 while 的选择性问题?

    • 明确知道循环次数的时候,毫不犹豫选择for

    • 不知道循环次数使用while循环

      1、for循环和while循环的区别
      	for循环的特点:初始化表达式只在当前的循环范围内有效。出了循环的大括号以外,就无法使用了
      	(tips:for循环的初始化表达式,也可以定义在外面)
          while循环的特点:初始化表达式是定义在循环的外面。出了循环也可以继续使用。
      
      2.do-while循环和for、while循环的区别
          do-while循环会至少先执行一遍循环体。然后再做条件判断
          而for、while循环都是先判断条件。如果条件满足才执行循环体。如果条件不满足,就直接结束循环
      
      3.使用场景
      	一般在循环次数确定的时候,推荐使用for循环
          一般在循环次数不确定的时候,推荐使用while循环
          do-while循环很少很少会用到
      
  5. 死循环

    while (true) {
    
    }
    
    for ( ; ; ) {
    
    }
    
    do {
    
    } while (true);
    
  6. 跳转控制语句

    break;
    // 在循环过程中,碰到break整个循环就直接结束了
    // break打断(终止)循环 只能用在循环和switch里面
    
    continue;
    // 如果在循环过程中碰到了continue,则跳过本次循环,进入下次循环
    

(十一)数组

  1. 概念:用来存储同种数据类型的多个数据的容器

  2. 数组存在的意义就是方便管理和操作一组数据

  3. 定义格式:数据类型 [ ] 变量名

  4. 初始化

    1. 动态初始化:数据类型[] 数组名 = new 数据类型[数组长度];
    2. 静态初始化:数据类型[] 数组名 = {元素值1,元素值2,元素值3,...};
  5. 数组元素的表示方式:数组名[索引]

    注意:索引值从0开始,一直到“数组的长度-1”为止。

  6. java内存中的几块区域(重要的)


    1. 方法被调用的时候都会入栈
      局部变量都被保存在栈中

    2. new出来的东西都在堆中
      堆中的东西都有默认初始化值

    局部变量:定义在方法中的变量

  7. 数组的实体保存在堆中
    数组名实际保存的是数组实体的地址值

  8. 数组长度的表示:数组名.length

    9.1数组的动态初始化:必须得给数组指定长度
    	int[] ageArray = new int[6];
    9.2索引
        1)特点:
            是一个整数
            范围:范围 0 ~ 数组长度-1
        2)使用索引来给数组赋值		数组名[索引值]
    9.3使用索引来访问数组当中的值		数组名[索引值]
    	int a = ageArray[0];
    9.4遍历赋值
        for (int i = 0; i < arr.length; i++) {
            arr[i] = 18;
        }
    9.5遍历取值
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    

(十二)二维数组

  1. 概念:二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组。

  2. 定义格式:数据类型[ ] [ ] 变量名;

    1. 动态初始化:数据类型 [ ] [ ] 变量名 = new 数据类型[ m ] [ n ];
    2. 静态初始化:数据类型 [ ] [ ] 变量名 = new 数据类型[ ] [ ] { {元素1,元素2}, {元素1, 元素2} };
  3. 元素访问:数组名 [n] [m]

  4. 遍历:

    // 外层循环控制行
    for (int i = 0; i < arr.length; i++) {
    	// 内层循环控制列
    	for (int j = 0; j < arr[i].length; j++) {
    		System.out.print(arr[i][j] + "\t");
    	}
    }
    

(十三)方法

  1. 概念:一段具有独立功能的代码块,不调用就不执行。

    ​ 代码块:在一对大括号中的多行代码

  2. 作用:提高代码的复用性

  3. 通用版本:

    public static  返回值类型  方法名(参数类型 参数名,参数类型2 参数名2,.....){
    	方法体;
    	return 返回值;
    }
    
    - (调用方法后,需不需要执行进一步的逻辑)
    - (必须配合return关键字使用)
    - (返回值类型必须与返回值相同)
    
    快速提取方法:Ctrl + Alt + M
    
  4. 方法的调用:方法名(参数1,参数2...);

    形参:全称形式参数,是指方法定义中的参数

    实参:全称实际参数,方法调用中的参数

  5. 三要素:返回值、方法名、参数类型

  6. 方法签名:方法名 + 参数列表

  7. 注意事项:

    1. 方法不能嵌套定义,各个方法之间是平级关系
    2. 方法的返回值类型为void,表示该方法没有返回值,没有返回值的方法可以省略return语句不写。如果要编写return,后面不能跟具体的数据
  8. 问题:为什么要有带返回值的方法?

    我们经常会根据一个方法产出的结果,来去组织另外一段代码逻辑
    为了拿到这个方法产生的结果,就需要定义带有返回值的方法

  9. 方法重载

    在同一个类中,方法名相同,参数列表不同的方法叫重载
    参数列表不同:
    	参数个数不同
    	参数类型不同
    	参数的多参数顺序不同
    注意:
    	看参数列表是否相同的时候和参数名没有关系
    

(十四)引用数据类型

  • String
  • Scanner、Random
  • 数组
  • 定义的类

三、面向对象

目标

类、对象、封装、构造方法

面向对象:面试官面向面试者,公司使用我是来实现某些需求。

思路

-> 理论概念 -> 代码结构 -> 项目搭建 ->

面向过程编程:是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的。

面向对象编程:是一种以对象为中心的编程思想,通过指挥对象实现具体的功能。

(一)类

类是对现实世界同一类具有共同属性行为的事物的抽象

  1. 类是创建对象的模板
  2. 组成
    • 属性:成员变量
    • 行为:成员方法(没有 static 关键字)
  3. 顺序:属性、构造方法、行为、get()、set()方法、toString()
  4. 一个类就是一个数据类型

(二)对象

对象:某一类事物的具体体现,是类的具体体现

  1. 对于对象,通过对 对象的抽象来得到类,再通过对类的 实例化,得到对象。

  2. 创建对象的格式:

    类名 对象名 = new 类名();

    快捷写法:new 类名().var

  3. 使用格式

    • 成员变量(属性):对象名.成员变量名;
    • 成员方法(行为):对象名.成员方法名(参数);
  4. set() 方法 与 get() 方法

    •   // private 关键字的作用:只能被本类使用,其他类无法访问(目的:变量保护)
        // public 公有的,所有的类均可访问
        private int age;
        
        // 并不是所有属性都要提供 get()、set()方法
        
        // set()方法
        public int getAge() {
            return age;
        }
        // get()方法
        public void setAge(int age) {
                this.age = age;
        }
      
    • this 关键字

      • this可以用来区分局部变量和成员变量同名的问题

      • this代表什么?

        代表当前对象的引用。谁来调用这个方法,this就代表谁

  5. 成员变量和局部变量的区别

     1.定义位置
         成员变量:定义在类中方法外。作用于整个类中
         局部变量:定义在方法内或方法的声明上。作用于方法里
     2.在内存中的位置
     	成员变量:在堆内存中
     	局部变量:在栈内存中
     3.生命周期
     	成员变量:随着对象的创建而创建。随着对象的消失而消失
     	局部变量:随着方法的调用而创建。随着方法的消失而消失
     4.初始化值
     	成员变量:有默认初始化值
     	局部变量:没有默认初始化值。使用之前必须赋值
    
  6. 文档注释

    类、属性

  7. 区别

    • public 类名() { } —— 构造方法

    • public void 方法名() { } —— 成员方法

    • public static void 方法名() { } —— 方法

    • public static void main(String[] args) { } —— 主方法

    • public class 类名() { } —— 类

  8. 类中的方法在堆内存中只保留成员方法的地址,指向 方法区的 成员方法名.class 文件。在被调用时进栈执行。

(三)构造方法(构造器)

  1. 特点

    • 类名和方法名相同
    • 没有返回值类型,连void都不能写
  2. 调用格式

    new 类名(参数);

  3. 注意

    • 每一个类都有默认的无参构造器
    • 写了任意一个有参构造器,无参构造器使用需手动增添
    • 有参构造器赋值和set方法赋值的区别:
      • 有参构造器只能给对象属性赋值一次
      • set方法可以重复修改值
    • 尽管只需要使用构造器赋值一次,但也只适用于属性不多的情况(5次)

(四)封装

  1. 概念:将不想对外暴露的属性隐藏起来,对外提供一些方法供别人去操作,这样可以更安全,也可以提高代码的复用性,结果就是形成一个标准的JavaBean。

    简化:属性私有化,并且提供相应的private和get()、set()方法

  2. 一个标准的类( JavaBean):

    所有的成员变量都用private修饰
    提供对应的getXxx/setXxx方法
    提供空参构造,全参构造

四、String

目标

API 的使用

String 引用数据类型的了解和常见构造方法

StringBuilder 与 String 相互使用

思路

学习API的方法(定义 -> 实现)

(一)API

  1. Java API :指的就是 JDK 中提供的各种功能的
  2. Java类:具有某种功能的方法

(二)next()与nextLine()

方法 结束标记 弊端
next() 空格 丢失数据
nextLine() 回车换行 缺少录入机会

nextInt 数据 + 回车换行 影响 nextLine(存在换行的原因)

(三)String概述

  • String 类在 java.lang 包下,所以使用的时候不需要导包

  • Java 程序中所有的双引号字符串,都是 String 类的对象

  • 字符串不可变,它们的值在创建后不能被更改

  • 输出String的原因:toString 方法

(四)String 常见构造方法

  1. 方法

image-20230327201839928

  1. 创建字符串对象的区别对比
  • 如果是直接赋值字符串常量它会存储在字符串常量池中 有复用机制

  • 每次new都肯定会创建一个新对象

  • 字符串常量池:当使用双引号创建字符串对象的时候,系统会检查该字符串是否在字符串常量池中存在

    不存在:创建 存在:不会重新创建,而是直接复用

(五)String的特点

  • Java 程序中所有的双引号字符串,都是 String 类的对象
  • 字符串不可变,它们的值在创建后不能被更改
  • 调用String的任意成员方法,这个String对象的内容都不会发生变化。最多返回值是变化后的结果

(六)常用方法

工作中

方法 功能
boolean equals(Object anObject); 将此字符串与指定的对象比较。区分大小写
String trim(); 返回字符串的副本,忽略前导空白和尾部空白
toUpperCase(); 将此 String 中的所有字符都转换为大写
toLowerCase(); 将此 String 中的所有字符都转换为小写
startsWith(); 测试此字符串是否以指定的前缀开始
boolean endsWith(String suffix); 测试此字符串是否以指定的后缀结束
boolean contains(CharSequence s); 当且仅当此字符串包含指定的 char 值序列时,返回 true

概念

方法 功能
int length(); 获得字符串的长度
char charAt(int index); 获取传入的索引上的对应的字符
char[] toCharArray(); 把字符串转化成字符数组
String substring(int index); 从指定位置开始截取。默认到末尾
String substring(int start,int end); 截取指定范围的字符串。包含开始、不包含结束
String replace(char oldStr,char newStr); 把字符串中的字符'a'全部替换成'b'
replaceAll
String[] split(String regex); 按照指定规则切割字符串

(七)常用方法的使用

s1.equals(s2)

s.trim();
// 大 -> 小
s.toUpperCase();
// 小 -> 大
s.toLowerCase();

s.length()

char c = str.charAt(i);
System.out.println(c);
    
String s = sc.nextLine();
char[] chars = s.toCharArray();
for (int i = 0; i < chars.length; i++) {
    System.out.println(chars[i]);
}

String str = "Hello World";
System.out.println(str.substring(8));
System.out.println(str.substring(3, 15));

String str1 = str.replace("o", "**")

String[] sArr = str.split(" ");

(八)StringBuilder

  1. StringBuilder概述

    StringBuilder 是一个可变的字符串类,我们可以把它看成一个容器。

  2. 构造方法

    StringBuilder sb = new StringBuilder(); 空

    StringBuilder sb2 = new StringBuilder("abc"); 字符串内容

  3. 成员方法

    方法名 功能
    StringBuilder append(Object obj) 向缓冲区添加内容
    StringBuilder reverse() 将缓冲区内容进行反转
    toString() 把StringBuilder转换成String
    length() 返回值StringBuilder的长度
  4. 方法的使用

    StringBuilder sb = new StringBuilder();
    sb.append(123);		返回对象本身
    sb.reverse();
    String s = sb.toString();
    int n = s.length();
    
  5. StringBuilder 提高字符串的操作效率

    当字符串之间使用 + 号串联(拼接)的时候,系统底层会自动创建一个 StringBuilder 对象

    然后再调用 append() 方法完成拼接

    拼接后,再调用其 toStrng() 方法转换成 String 类型

  6. 字符串的地址问题

    String str1 = "ab"; // 创建新地址
    String str2 = "c";	// 创建新地址
    String str3 = str1 + str2; // 创建新地址
    String str4 = "abc";  // 创建新地址
    
    // 字符串常量池(方法区)
    String str5 = "ab" + "c";  // 同 str4
    
    String str6 = new String("abc");  // 创建新地址
    

五、集合

目标

构造方法、成员方法的使用

与类的交叉使用

思路

集合是一个容器,可以存放多个类,每一个类能够拥有同种的属性和行为

(一)概述

  • 集合就是用来存储多个数据的容器

(二)集合和数组的区别

  • 数组的长度一旦创建就不能修改
  • 集合是一个存储空间可变的容器

(三)构造方法

ArrayList list = new ArrayList<>();

ArrayList list = new ArrayList();

<>只能存引用数据类型

(四)成员方法

image-20230328125507337

(五)方法使用

list.remove(index);
list.set(index, stu);
Student stu = list.get(i);
list.size()

六、学生管理系统

目标

集合的方法使用

add、remove、get、set、size

思想

  1. 搭建主界面菜单
  2. 创建集合容器对象
  3. 通过语句实现系统
  4. 通过方法实现功能

(一)学生类

学号、姓名、年龄、生日

属性、构造方法、get set方法

(二)输出菜单

Scanner while循环 switch语句

(三)创建集合容器对象

ArrayList<Student> list = new ArrayList<>();

(四)添加学生功能

  1. 判断学号是否存在
  2. 录入学生信息
  3. 创建学生类对象
  4. 将学生类对象添加到集合中

(五)删除学生功能

  1. 输入要删除的学生学号
  2. 键盘录入
  3. 通过索引找出方法查询是否存在该学生的学号
  4. 不存在,给出提示;存在则删除索引值所指向的集合位置

(六)修改学生功能

  1. 输入要修改的学生学号
  2. 键盘录入
  3. 通过索引查找
  4. 不存在,给出提示;存在进行下一步
  5. 录入新的学生信息
  6. 封装为新的学生对象
  7. 通过 set 方法修改

(七)查看学生功能

  1. 判断集合中是否存在数据

  2. 打印表头

  3. 输出每一个对象的数据

    • 遍历集合
    • 创建类接收单个对象
    • 打印对象的每一个属性

(八)获取对象中学号的索引位置

  1. 假设索引为 -1 即不存在
  2. 遍历集合,创建类接收单个对象,获取对象的学号
  3. 使用 equals 方法将对象学号与查找学号进行对比
  4. 若为 true 则修改索引为当前集合循环的索引值
  5. 返回索引