JavaSE基础
一、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)多行注释:/* 注释信息 */
(3)文档注释:/** 注释信息 */
(二)标识符
-
概念:起名字时使用的字符序列
-
命名规则:
(1)字母、数字、下划线( _ )、$
(2)不能使用数字开头
(3)不能使用 Java 的关键字
(4)区分大小写
-
命名规范:
(1)类、接口:(大驼峰命名)
- 每一个单词的首字母都采用大写字母
(2)变量、方法:(小驼峰命名)
- 第一个单词以小写字母开始,第二个及以后的每个单词的首字母大写
(3)常量:
- 字母全部大写
(三)关键字
- 概念:java中有特殊意义的词
- 特点:
- 完全是小写的字母
- 常见的开发软件中会有特殊颜色标识
- 特殊:main不是关键字,但是是一个会被 JVM 识别的特殊的单词
(四)数据类型
-
计算机存储单元
- 位(bit) 又称之为 比特位
- 字节(Byte)是计算机数据存储的最小单位
-
数据类型(默认:整数 int 小数 double)
-
基本数据类型
-
数值型
- 整数:byte, short, int, long
- 浮点数:float, double
- 字符:char
-
非数值型
布尔:boolean
-
-
引用数据类型
- 类:class
- 接口:interface
- 数组:[ ]
-
-
默认值
- 整型数组默认值都是0
- 浮点数组 0.0
- 布尔类型 false
- 字符char 空格
- 所有的引用类型数组默认值都是 null
(五)变量与常量
- 变量
- 概念:变量就是内存中可以发生改变的量。
- 定义格式:数据类型 变量名 = 初始值;
- 注意事项:
- 变量使用不能超过作用域的范围。
【作用域】:从定义变量的一行开始,一直到直接所属的大括号结束为止。 - 可以通过一个语句来创建多个变量,但是一般情况不推荐这么写。
- 变量使用不能超过作用域的范围。
- 常量
- 概念:在程序运行过程中固定不变的量。
- 定义格式:final 数据类型 变量名 = 常量值;
(六)运算符
-
算术运算符:+ - * / % ++ --
+ 在输出语句中,+连接符的前方,如果有字符串参与,那就不是加法,是字符串拼接,并且拼接后的结果仍是字符串。 倘若需要在字符串后进行加法运算,则需要在两侧加上括号 / 多个整数相除,如果要想得到小数结果,必须得有一个小数参与运算
-
赋值运算符:= += -= *= /= %= 扩展赋值运算符底层自带强转功能
-
比较(关系)运算符:== < > <= >= !=
-
逻辑运算符:&& || ! ^ & |
-
三目运算符:数据类型 变量名= 比较表达式 ? 表达式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
(七)类型转换
概念:把一种数据类型直接赋值给另外一种数据类型称为数据类型的转换。
-
隐式类型转换
-
概念:又叫做自动类型转换,系统自动把小类型转为大类型。
-
数据范围
byte -> short -> int -> long -> float -> double
char ↑
-
定义 float 类型时必须在数字后面跟上 F 或者 f
-
-
强制类型转换
- 概念:大的数据转为小数据类,系统不能自动完成。
- 格式:小类型 变量名 = (小类型)大类型数据变量
- 注意:应该尽量避免出现强制转型,因为会产生精度损失,数据溢出。
(八)键盘录入
三个步骤:导包、创建对象、接收数据
// 导包的动作必须出现在类定义的上面
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("不符合");
}
}
(九)分支语句
-
if 语句
-
格式 1:
if (比较表达式) { 语句体; }
-
格式 2:
if (比较表达式1) { 语句体1; }else { 语句体2; }
-
格式 3:
if (比较表达式1) { 语句体1; } else if (比较表达式2) { 语句体2; } else if (比较表达式3){ 语句体3; } else { 语句体n; }
-
-
switch 语句
switch (普通表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; case 值3: 语句体3; break; ... default: 语句体n+1; break; } // 最后一个break语句可以省略,但是强烈推荐不要省略
注意:
- 只能匹配byte short char int String 枚举
- default 必须存在
- 如果不加 break 就会出现case 穿透
-
if 和 switch 选择问题
如果表达式符合switch的条件,并且分支超过三个以上,这时应该用switch
(十)循环语句
-
for 语句
for (初始化语句; 比较表达式; 步进语句) { 循环体; } // 1.初始化语句 表示本次循环从第几次开始 // 2.比较语句 表示本次循环到第几次结束 // 3.步进语句 表示每循环一次,循环变量变化多少 // 循环流程 // 1.先执行初始化语句,并且只执行一次 // 2.执行比较语句,如果为true则执行循环体 // 3.执行步进语句 // 作用域有大小,大的作用域无法访问小的作用域内的变量 // 反过来,小的作用域可以访问大的作用域的变量
-
while 语句
while (比较表达式) { 循环体; } 执行流程 看判断表达式的结果,如果为false循环结束,如果为true则执行循环体。 循环体执行完后继续看判断表达式的结果以此类推 // for 和 while 的选择性问题 // 明确知道循环次数的时候,毫不犹豫选择 for // 不知道循环次数使用 while 循环
-
do...while 语句
do { 循环体; } while (比较表达式); 执行流程 先执行循环体,然后看判断表达式的结果。如果为true则继续执行循环体 如果判断表达式的结果为false则循环结束,如此反复。
-
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循环很少很少会用到
-
-
死循环
while (true) { } for ( ; ; ) { } do { } while (true);
-
跳转控制语句
break; // 在循环过程中,碰到break整个循环就直接结束了 // break打断(终止)循环 只能用在循环和switch里面 continue; // 如果在循环过程中碰到了continue,则跳过本次循环,进入下次循环
(十一)数组
-
概念:用来存储同种数据类型的多个数据的容器
-
数组存在的意义就是方便管理和操作一组数据
-
定义格式:数据类型 [ ] 变量名
-
初始化
- 动态初始化:数据类型[] 数组名 = new 数据类型[数组长度];
- 静态初始化:数据类型[] 数组名 = {元素值1,元素值2,元素值3,...};
-
数组元素的表示方式:数组名[索引]
注意:索引值从0开始,一直到“数组的长度-1”为止。
-
java内存中的几块区域(重要的)
- 栈
方法被调用的时候都会入栈
局部变量都被保存在栈中 - 堆
new出来的东西都在堆中
堆中的东西都有默认初始化值
局部变量:定义在方法中的变量
- 栈
-
数组的实体保存在堆中
数组名实际保存的是数组实体的地址值 -
数组长度的表示:数组名.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]); }
(十二)二维数组
-
概念:二维数组也是一种容器,不同于一维数组,该容器存储的都是一维数组。
-
定义格式:数据类型[ ] [ ] 变量名;
- 动态初始化:数据类型 [ ] [ ] 变量名 = new 数据类型[ m ] [ n ];
- 静态初始化:数据类型 [ ] [ ] 变量名 = new 数据类型[ ] [ ] { {元素1,元素2}, {元素1, 元素2} };
-
元素访问:数组名 [n] [m]
-
遍历:
// 外层循环控制行 for (int i = 0; i < arr.length; i++) { // 内层循环控制列 for (int j = 0; j < arr[i].length; j++) { System.out.print(arr[i][j] + "\t"); } }
(十三)方法
-
概念:一段具有独立功能的代码块,不调用就不执行。
代码块:在一对大括号中的多行代码
-
作用:提高代码的复用性
-
通用版本:
public static 返回值类型 方法名(参数类型 参数名,参数类型2 参数名2,.....){ 方法体; return 返回值; } - (调用方法后,需不需要执行进一步的逻辑) - (必须配合return关键字使用) - (返回值类型必须与返回值相同) 快速提取方法:Ctrl + Alt + M
-
方法的调用:方法名(参数1,参数2...);
形参:全称形式参数,是指方法定义中的参数
实参:全称实际参数,方法调用中的参数
-
三要素:返回值、方法名、参数类型
-
方法签名:方法名 + 参数列表
-
注意事项:
- 方法不能嵌套定义,各个方法之间是平级关系
- 方法的返回值类型为void,表示该方法没有返回值,没有返回值的方法可以省略return语句不写。如果要编写return,后面不能跟具体的数据
-
问题:为什么要有带返回值的方法?
我们经常会根据一个方法产出的结果,来去组织另外一段代码逻辑
为了拿到这个方法产生的结果,就需要定义带有返回值的方法 -
方法重载
在同一个类中,方法名相同,参数列表不同的方法叫重载 参数列表不同: 参数个数不同 参数类型不同 参数的多参数顺序不同 注意: 看参数列表是否相同的时候和参数名没有关系
(十四)引用数据类型
- String
- Scanner、Random
- 数组
- 定义的类
三、面向对象
目标
类、对象、封装、构造方法
面向对象:面试官面向面试者,公司使用我是来实现某些需求。
思路
-> 理论概念 -> 代码结构 -> 项目搭建 ->
面向过程编程:是一种以过程为中心的编程思想,实现功能的每一步,都是自己实现的。
面向对象编程:是一种以对象为中心的编程思想,通过指挥对象实现具体的功能。
(一)类
类是对现实世界同一类具有共同属性和行为的事物的抽象
- 类是创建对象的模板
- 组成
- 属性:成员变量
- 行为:成员方法(没有 static 关键字)
- 顺序:属性、构造方法、行为、get()、set()方法、toString()
- 一个类就是一个数据类型
(二)对象
对象:某一类事物的具体体现,是类的具体体现
-
对于对象,通过对 对象的抽象来得到类,再通过对类的 实例化,得到对象。
-
创建对象的格式:
类名 对象名 = new 类名();
快捷写法:new 类名().var
-
使用格式
- 成员变量(属性):对象名.成员变量名;
- 成员方法(行为):对象名.成员方法名(参数);
-
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就代表谁
-
-
-
成员变量和局部变量的区别
1.定义位置 成员变量:定义在类中方法外。作用于整个类中 局部变量:定义在方法内或方法的声明上。作用于方法里 2.在内存中的位置 成员变量:在堆内存中 局部变量:在栈内存中 3.生命周期 成员变量:随着对象的创建而创建。随着对象的消失而消失 局部变量:随着方法的调用而创建。随着方法的消失而消失 4.初始化值 成员变量:有默认初始化值 局部变量:没有默认初始化值。使用之前必须赋值
-
文档注释
类、属性
-
区别
-
public 类名() { } —— 构造方法
-
public void 方法名() { } —— 成员方法
-
public static void 方法名() { } —— 方法
-
public static void main(String[] args) { } —— 主方法
-
public class 类名() { } —— 类
-
-
类中的方法在堆内存中只保留成员方法的地址,指向 方法区的 成员方法名.class 文件。在被调用时进栈执行。
(三)构造方法(构造器)
-
特点
- 类名和方法名相同
- 没有返回值类型,连void都不能写
-
调用格式
new 类名(参数);
-
注意
- 每一个类都有默认的无参构造器
- 写了任意一个有参构造器,无参构造器使用需手动增添
- 有参构造器赋值和set方法赋值的区别:
- 有参构造器只能给对象属性赋值一次
- set方法可以重复修改值
- 尽管只需要使用构造器赋值一次,但也只适用于属性不多的情况(5次)
(四)封装
-
概念:将不想对外暴露的属性隐藏起来,对外提供一些方法供别人去操作,这样可以更安全,也可以提高代码的复用性,结果就是形成一个标准的JavaBean。
简化:属性私有化,并且提供相应的private和get()、set()方法
-
一个标准的类( JavaBean):
所有的成员变量都用private修饰
提供对应的getXxx/setXxx方法
提供空参构造,全参构造
四、String
目标
API 的使用
String 引用数据类型的了解和常见构造方法
StringBuilder 与 String 相互使用
思路
学习API的方法(定义 -> 实现)
(一)API
- Java API :指的就是 JDK 中提供的各种功能的
- Java类:具有某种功能的方法
(二)next()与nextLine()
方法 | 结束标记 | 弊端 |
---|---|---|
next() | 空格 | 丢失数据 |
nextLine() | 回车换行 | 缺少录入机会 |
nextInt 数据 + 回车换行 影响 nextLine(存在换行的原因)
(三)String概述
-
String 类在 java.lang 包下,所以使用的时候不需要导包
-
Java 程序中所有的双引号字符串,都是 String 类的对象
-
字符串不可变,它们的值在创建后不能被更改
-
输出String的原因:toString 方法
(四)String 常见构造方法
- 方法
- 创建字符串对象的区别对比
-
如果是直接赋值字符串常量它会存储在字符串常量池中 有复用机制
-
每次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
-
StringBuilder概述
StringBuilder 是一个可变的字符串类,我们可以把它看成一个容器。
-
构造方法
StringBuilder sb = new StringBuilder(); 空
StringBuilder sb2 = new StringBuilder("abc"); 字符串内容
-
成员方法
方法名 功能 StringBuilder append(Object obj) 向缓冲区添加内容 StringBuilder reverse() 将缓冲区内容进行反转 toString() 把StringBuilder转换成String length() 返回值StringBuilder的长度 -
方法的使用
StringBuilder sb = new StringBuilder(); sb.append(123); 返回对象本身 sb.reverse(); String s = sb.toString(); int n = s.length();
-
StringBuilder 提高字符串的操作效率
当字符串之间使用 + 号串联(拼接)的时候,系统底层会自动创建一个 StringBuilder 对象
然后再调用 append() 方法完成拼接
拼接后,再调用其 toStrng() 方法转换成 String 类型
-
字符串的地址问题
String str1 = "ab"; // 创建新地址 String str2 = "c"; // 创建新地址 String str3 = str1 + str2; // 创建新地址 String str4 = "abc"; // 创建新地址 // 字符串常量池(方法区) String str5 = "ab" + "c"; // 同 str4 String str6 = new String("abc"); // 创建新地址
五、集合
目标
构造方法、成员方法的使用
与类的交叉使用
思路
集合是一个容器,可以存放多个类,每一个类能够拥有同种的属性和行为
(一)概述
- 集合就是用来存储多个数据的容器
(二)集合和数组的区别
- 数组的长度一旦创建就不能修改
- 集合是一个存储空间可变的容器
(三)构造方法
ArrayList
ArrayList
<>只能存引用数据类型
(四)成员方法
(五)方法使用
list.remove(index);
list.set(index, stu);
Student stu = list.get(i);
list.size()
六、学生管理系统
目标
集合的方法使用
add、remove、get、set、size
思想
- 搭建主界面菜单
- 创建集合容器对象
- 通过语句实现系统
- 通过方法实现功能
(一)学生类
学号、姓名、年龄、生日
属性、构造方法、get set方法
(二)输出菜单
Scanner while循环 switch语句
(三)创建集合容器对象
ArrayList<Student> list = new ArrayList<>();
(四)添加学生功能
- 判断学号是否存在
- 录入学生信息
- 创建学生类对象
- 将学生类对象添加到集合中
(五)删除学生功能
- 输入要删除的学生学号
- 键盘录入
- 通过索引找出方法查询是否存在该学生的学号
- 不存在,给出提示;存在则删除索引值所指向的集合位置
(六)修改学生功能
- 输入要修改的学生学号
- 键盘录入
- 通过索引查找
- 不存在,给出提示;存在进行下一步
- 录入新的学生信息
- 封装为新的学生对象
- 通过 set 方法修改
(七)查看学生功能
-
判断集合中是否存在数据
-
打印表头
-
输出每一个对象的数据
- 遍历集合
- 创建类接收单个对象
- 打印对象的每一个属性
(八)获取对象中学号的索引位置
- 假设索引为 -1 即不存在
- 遍历集合,创建类接收单个对象,获取对象的学号
- 使用 equals 方法将对象学号与查找学号进行对比
- 若为 true 则修改索引为当前集合循环的索引值
- 返回索引