Java开发环境搭建
理论篇
-
Java简介与应用
- 由 James Gosling 1995 年在 Sun 开发,2009 年并入 Oracle。
- 覆盖面广:企业级应用、服务端开发为主(本课程以 JavaSE 打基础,进阶 JavaEE,JavaME 了解即可)。
-
JDK 与版本选择
- JDK:Java Development Kit,开发必备。
- 优先选择 LTS(长期支持)版;课程使用 JDK 21(便于学习新特性)。
-
JDK 组成与工具
- JRE:Java 运行环境。
- JVM:Java 虚拟机,跨平台核心。
- 开发工具:javac(编译器)、java(运行器)等,位于 JDK 的 bin 目录。
-
Java 程序执行与跨平台
- 开发流程:.java 源码 → javac 编译为 .class 字节码 → JVM 解释执行。
- 跨平台原理:不同操作系统安装对应 JVM,统一执行同一份字节码。
-
DOS/命令行基础
- 需要会用命令行执行 javac/java。
- 常用命令:cd、dir、cls、md、rd、del、copy、move、type、exit。
-
Path 环境变量与 JAVA_HOME
- Path:让系统在任意目录识别并执行指定程序(如 javac、java)。
- JAVA_HOME:指向 JDK 安装目录,供工具链统一引用;推荐 Path 使用 %JAVA_HOME%\bin。
-
IDEA(集成开发环境)
- 一体化:编辑、编译、运行、调试。
- 项目结构:项目(Project)/ 模块(Module)/ 类(Class)。
- 建议使用稳定版本(如 2024.1),避免最新版本潜在问题。
代码篇
JDK 安装与校验
作用/概念简述
- 安装 JDK 并在命令行验证 javac/java 是否可用,确认开发环境可正常编译、运行 Java 程序。
通用模版
- 安装路径建议无中文、无空格(例如:C:\Java\jdk-21)
- 命令行校验:
java -version
javac -version
属性/知识点表格
校验项 | 预期结果 | 说明 |
---|---|---|
java -version | 显示 JDK 版本信息 | Java 运行时可用 |
javac -version | 显示编译器版本 | 编译器可用 |
JDK 目录结构 | bin/conf/lib | 工具/配置/库所在位置 |
片段代码案例
C:\> java -version
java version "21" 2023-09-19
Java(TM) SE Runtime Environment (build 21+35)
Java HotSpot(TM) 64-Bit Server VM (build 21+35, mixed mode, sharing)
C:\> javac -version
javac 21
配置 Path 与 JAVA_HOME(Windows)
作用/概念简述
- 将 JDK 工具加入系统 Path,命令行即可在任意目录使用;通过 JAVA_HOME 统一指向 JDK 根目录,便于其他工具查找。
通用模版
- 系统环境变量:
- 新建 JAVA_HOME:指向 JDK 根目录(例如 C:\Java\jdk-21)
- 编辑 Path:添加
%JAVA_HOME%\bin
- 确认顺序:确保优先级高于旧 JDK 或 JRE 路径
属性/知识点表格
变量名 | 示例值 | 作用 |
---|---|---|
JAVA_HOME | C:\Java\jdk-21 | 标准 JDK 根路径 |
Path | %JAVA_HOME%\bin | 任意目录使用 javac/java |
片段代码案例
C:\> echo %JAVA_HOME%
C:\Java\jdk-21
C:\> where java
C:\Java\jdk-21\bin\java.exe
C:\Windows\System32\java.exe ← 若存在,需调整 Path 顺序或卸载旧 JRE
常用 DOS 命令
作用/概念简述
- 熟悉命令行下的目录/文件操作,以便编译运行 Java 程序。
通用模版
- 基本导航与操作:
cd 目录 切换目录
cd .. 返回上级
dir 查看当前目录文件
cls 清屏
md 名称 新建目录
rd 名称 删除目录(空)
del 文件 删除文件
copy 源 目标 复制
move 源 目标 移动/重命名
type 文件 查看文本内容
exit 退出
属性/知识点表格
命令 | 示例 | 说明 |
---|---|---|
cd | cd C:\work\java | 切换目录 |
dir | dir | 列表显示 |
md | md src | 创建目录 |
del | del HelloWorld.class | 删除文件 |
type | type HelloWorld.java | 查看源码 |
片段代码案例
C:\> md demo
C:\> cd demo
C:\demo> type nul > HelloWorld.java (或使用编辑器新建)
C:\demo> dir
HelloWorld:编写、编译、运行
作用/概念简述
- 使用最小 Java 程序验证编译运行流程与环境正确性。
通用模版
- HelloWorld.java:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, Java!");
}
}
- 编译与运行:
javac HelloWorld.java
java HelloWorld
属性/知识点表格
步骤 | 命令/要点 | 常见问题 |
---|---|---|
编译 | javac HelloWorld.java | 文件未保存、路径不对、编码问题 |
运行 | java HelloWorld | 不带 .class;类名与文件名一致 |
文件扩展名 | .java | Windows 显示扩展名需开启 |
片段代码案例
C:\demo> javac HelloWorld.java
C:\demo> java HelloWorld
Hello, Java!
Java 执行原理(可选拓展)
作用/概念简述
- 观察字节码,理解 .java → .class → JVM 的执行过程。
通用模版
- 使用 javap 反编译字节码(仅演示用):
javap -c HelloWorld
属性/知识点表格
工具 | 用途 | 备注 |
---|---|---|
javac | 编译源码生成字节码 | 面向 JVM |
javap | 反编译字节码 | 学习/排错 |
片段代码案例
C:\demo> javap -c HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld {
public HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Hello, Java!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
IDEA 快速起步(项目/模块/类)
作用/概念简述
- 使用 IDEA 创建项目与模块,配置 JDK,编写并运行 Java 类。
通用模版
- 关键步骤:
- 新建 Project → 选择 JDK 21 → 创建空项目或直接带模块
- 新建 Module(Java)→ 关联 SDK(JDK 21)
- 新建 Class(含 main)
- 运行:右键类文件 → Run 或使用运行快捷键
属性/知识点表格
概念 | 含义 | 说明 |
---|---|---|
Project | 项目 | 顶层容器 |
Module | 模块 | 可独立编译/运行 |
Class | 类文件 | 源码单元 |
SDK | JDK | 项目/模块使用的 JDK |
片段代码案例
public class Main {
public static void main(String[] args) {
System.out.println("Run in IDEA");
}
}
- 常用操作(示例快捷键,Windows 默认):
- 新建类:Alt + Insert
- 运行当前类:Ctrl + Shift + F10
- 重命名:Shift + F6
常见错误与排查清单
作用/概念简述
- 快速定位初学阶段的高频问题,保证编译运行稳定。
通用模版
- 排查顺序:
- 文件名与类名一致,且 public 类名正确
- 已保存源码文件,扩展名为 .java(非 .txt)
- 命令位置在源码所在目录
- 运行命令不带 .class
- JAVA_HOME、Path 配置正确
- 命令行输出编码与文件编码一致(避免中文乱码)
属性/知识点表格
现象 | 可能原因 | 解决 |
---|---|---|
‘javac’ 不是内部或外部命令 | Path 未配置 | 配置 %JAVA_HOME%\bin |
找不到或无法加载主类 | 类名/包名错误、路径错误 | 确认类名与文件名一致,运行目录正确 |
中文乱码 | 控制台/文件编码不一致 | 统一为 UTF-8,必要时设置控制台编码 |
片段代码案例
C:\demo> where javac
C:\Java\jdk-21\bin\javac.exe
C:\demo> echo %JAVA_HOME%
C:\Java\jdk-21
Java基础语法
理论篇
-
注释
- 在程序中添加说明性信息,提升可读性与可维护性。单行注释 //、多行注释 /.../、文档注释 /**...*/。
- 注释内容不参与编译与运行。建议:一段代码10秒没看懂就加注释。
-
关键字与字面量
- 关键字:被 Java 赋予特殊含义的英文单词(如 public、class、int、return…),不能作为标识符使用。
- 字面量:直接在代码中书写的数据,如整型10,小数12.3,字符'男',字符串"张三",布尔true/false。
-
变量
- 概念:内存中的一块存储区域。格式:数据类型 变量名 = 数据值;
- 变量使用:打印、修改、运算。
- 注意事项:先声明后使用;类型匹配;作用域限制;同一作用域名不可重复;使用前必须赋值;一条语句可定义多个变量。
-
标识符
- 由字母、数字、下划线(_)、美元符($)组成,不能以数字开头,不能用关键字,区分大小写。
- 规范:见名知义,驼峰命名(类名大驼峰,方法/变量名小驼峰)。
-
数据类型
- 基本类型:byte/short/int/long(整数)、float/double(小数)、char(字符)、boolean(布尔)。
- 引用类型:类、接口、数组、字符串等。
- 使用建议:整数首选int,装不下用long(字面量加L);小数首选double,float需加F。
- 默认:整数默认int,小数默认double;char范围0~65535(底层为编码值)。
-
运算符
- 算术:+ - * / %。整数/整数结果为整数;% 取余。
- 字符串拼接:当 + 遇到字符串时为连接。
- 自增自减:a++/++a、a--/--a;单独使用等效;参与运算时前缀/后缀有差异。
- 赋值:=、+=、-=、*=、/=、%=(扩展赋值自带强转)。
- 关系:> >= < <= == != 返回布尔。
- 逻辑:& | ! ^ 与 或 非 异或;短路:&&、||(左侧可短路右侧)。
- 三元:条件 ? 值1 : 值2。
- 优先级:用小括号明确优先顺序即可。
-
类型转换
- 隐式转换:小范围到大范围(如 int→double),运算中会提升。
- 强制转换:大到小需强转,可能丢失精度。
- 表达式提升规则:byte/short/char 运算会提升为int。
-
Scanner 与 package
- Scanner:命令行输入(nextInt、next、...),三步:导包、创建对象、调用方法。
- package:按功能组织类文件,规范:公司域名倒写 + 模块(如 com.itheima.xxx)。
-
方法(函数)
- 概念:具有独立功能的代码块,不调用不执行。好处:复用、结构化、便维护。
- 定义:权限 修饰符 返回值类型 方法名(参数列表){方法体; [return 值;]}
- 分类:无参无返、带参、带返回值。
- 注意:方法之间平级,不能嵌套定义;void 方法可省略return;return 后不能有语句。
- 重载:同类中方法名相同,参数个数/类型/顺序不同,与返回值无关。
代码篇
注释
作用/概念简述
- 对代码进行说明的文本,增强可读性,不参与编译与运行。
通用模版
// 单行注释
/*
多行注释
*/
/**
* 文档注释(生成API文档用,初学了解)
*/
属性/知识点表格
类型 | 写法 | 用途 |
---|---|---|
单行注释 | // ... | 简短说明 |
多行注释 | /* ... */ | 大段说明/屏蔽代码 |
文档注释 | /** ... */ | 生成文档注释 |
片段代码案例
public class HelloWorld {
// main 是程序入口
public static void main(String[] args){
System.out.println(123);
System.out.println("HelloWorld"); // 输出语句
}
}
关键字与字面量
作用/概念简述
- 关键字:有特殊含义的保留词;字面量:数据的直接书写形式。
通用模版
// 关键字示例
public class Demo { }
// 字面量示例
System.out.println("张三");
System.out.println(23);
System.out.println(185.1);
System.out.println('男');
System.out.println(false);
属性/知识点表格
概念 | 示例 | 注意 |
---|---|---|
关键字 | public, class, int | 不能作标识符 |
字面量 | 10, 12.3, 'a', "abc", true | null 不能直接打印 |
片段代码案例
public class ConstantDemo {
public static void main(String[] args) {
System.out.println("张三");
System.out.println(23);
System.out.println(185.1);
System.out.println('男');
System.out.println(false);
}
}
变量定义与使用
作用/概念简述
- 变量:内存中的可变数据,格式:数据类型 变量名 = 数据值; 使用时通过变量名。
通用模版
数据类型 变量名 = 值;
变量名 = 新值;
System.out.println(变量名);
属性/知识点表格
要点 | 说明 |
---|---|
先声明后使用 | 否则报错 |
类型匹配 | int 装整数,double 装小数 |
作用域 | 在 {} 内有效 |
不重复命名 | 同一作用域不可重名 |
使用前赋值 | 未初始化不能使用 |
片段代码案例
int age = 18;
System.out.println(age); // 18
age = 20;
System.out.println(age + 10); // 30
int a = 10, b = 20, c = 30;
标识符命名
作用/概念简述
- 给类、方法、变量起名的规则与规范。
通用模版
- 规则:字母/数字/_/$,不能以数字开头,不能用关键字,区分大小写。
- 规范:见名知义;类(大驼峰),方法/变量(小驼峰)。
属性/知识点表格
类名 | 方法名 | 变量名 |
---|---|---|
HelloWorld | getMax | userName |
片段代码案例
public class UserInfo {
public static void printUser(String name, int age) {
int userAge = age;
System.out.println(name + ":" + userAge);
}
}
基本数据类型与选择
作用/概念简述
- Java 基本类型与使用建议;整数默认 int,小数默认 double。
通用模版
// 建议选择
int count = 100;
long tel = 15612341234L; // long 需加 L
double height = 180.1;
float weight = 65.5F; // float 需加 F
char gender = '男';
boolean flag = true;
属性/知识点表格
类别 | 类型 | 字面量示例 | 备注 |
---|---|---|---|
整数 | byte/short/int/long | 10, 100L | 首选 int;长整型加 L |
小数 | float/double | 12.3F, 12.3 | 首选 double |
字符 | char | 'a', '男' | 底层编码 0~65535 |
布尔 | boolean | true/false | 条件判断 |
片段代码案例
String name = "张三";
int age = 23;
char sex = '男';
double h = 180.1;
boolean ok = true;
System.out.println(name);
System.out.println(age);
System.out.println(sex);
System.out.println(h);
System.out.println(ok);
类型转换(隐式/强制)
作用/概念简述
- 隐式:小到大自动转换;强制:大到小需强转,可能丢精度。表达式中 byte/short/char 提升为 int。
通用模版
// 隐式
double d = 10; // 10 -> 10.0
// 强制
int n = (int)12.7; // 12(精度丢失)
属性/知识点表格
类型 | 场景 | 注意 |
---|---|---|
隐式 | int→double、float→double | 安全 |
强制 | double→int、long→int | 可能丢失精度 |
表达式提升 | byte/char→int | 结果 int |
片段代码案例
int a = 10;
double r1 = a + 2.5; // 12.5(隐式)
double b = 12.3;
int r2 = (int)b; // 12(强转)
int result = 'a' + 1; // 'a'->97,结果98
byte b1 = 3, b2 = 4;
// byte b3 = b1 + b2; // 错,提升为int
byte b3 = (byte)(b1 + b2); // 或 int b3 = b1 + b2;
算术运算符与取模
作用/概念简述
-
-
-
- / %;整数除法截断,取模求余数,用于位拆解等。
-
-
通用模版
a + b; a - b; a * b; a / b; a % b;
属性/知识点表格
表达式 | 结果 |
---|---|
5 / 2 | 2 |
5 / 2.0 | 2.5 |
5 % 2 | 1 |
片段代码案例
int num = 456;
int ge = num % 10;
int shi = num / 10 % 10;
int bai = num / 100;
System.out.println(ge); // 6
System.out.println(shi); // 5
System.out.println(bai); // 4
字符串拼接(+)
作用/概念简述
- 当 + 遇到字符串时执行连接操作,而非算术。
通用模版
"前缀" + 变量 + "后缀"
属性/知识点表格
场景 | 说明 |
---|---|
字符串连接 | 从左到右依次拼接 |
自动转换 | 其他类型转为字符串 |
片段代码案例
int num = 456;
int ge = num % 10, shi = num / 10 % 10, bai = num / 100;
System.out.println("整数" + num + "的个位为: " + ge);
System.out.println("整数" + num + "的十位为: " + shi);
System.out.println("整数" + num + "的百位为: " + bai);
自增自减运算符
作用/概念简述
- ++a/--a:先运算再使用;a++/a--:先使用再运算;单独使用无差别。
通用模版
int a = 10;
int b = ++a; // a=11, b=11
int c = 10;
int d = c++; // d=10, c=11
属性/知识点表格
形式 | 执行顺序 |
---|---|
前缀++ | 先自增,再参与其他运算 |
后缀++ | 先参与其他运算,再自增 |
片段代码案例
int x = 10;
int y = ++x; // x=11,y=11
int z = y--; // z=11,y=10
System.out.println(x); //11
System.out.println(y); //10
System.out.println(z); //11
int a = 3;
int b = (++a) + (a++) + (a * 10); // 4 + 4 + 50
System.out.println(a); //5
System.out.println(b); //58
赋值运算符(含扩展)
作用/概念简述
- 基本赋值=,扩展赋值(+=、-=、*=、/=、%=)自带强制转换效果。
通用模版
a += b; // a = (类型)a + b
属性/知识点表格
运算符 | 等价 |
---|---|
a += b | a = (类型)(a + b) |
a -= b | a = (类型)(a - b) |
片段代码案例
int a = 10;
a += 20; // 30
System.out.println(a);
int x = 10;
double y = 12.3;
x += y; // x = (int)(x + y) = 22
System.out.println(x);
关系运算符
作用/概念简述
- 比较两个操作数关系,结果为 boolean。
通用模版
> >= < <= == !=
属性/知识点表格
表达式 | 结果 |
---|---|
10 > 20 | false |
10 <= 20 | true |
10 == 20 | false |
10 != 20 | true |
片段代码案例
System.out.println(10 > 20);
System.out.println(10 >= 20);
System.out.println(10 < 20);
System.out.println(10 <= 20);
System.out.println(10 == 20);
System.out.println(10 != 20);
逻辑运算符(含短路)
作用/概念简述
- 组合多个布尔表达式;短路运算避免不必要求值。
通用模版
&(与) |(或) !(非) ^(异或) &&(短路与) ||(短路或)
属性/知识点表格
运算符 | 规则 |
---|---|
& | 遇 false 则 false |
! | 取反 |
^ | 相同 false,不同 true |
&& | 左 false 短路 |
片段代码案例
int x = 3, y = 4;
// 左边 false,右边不执行(短路)
boolean result = ++x > 5 && y-- < 4;
System.out.println(result); // false
System.out.println(x); // 4
System.out.println(y); // 4
三元运算符
作用/概念简述
- 根据条件从两个值中选其一。
通用模版
条件 ? 值1 : 值2;
属性/知识点表格
步骤 | 说明 |
---|---|
先判断 | 计算条件表达式 |
返回值 | true 取值1,false 取值2 |
片段代码案例
int a = 50, b = 20;
int max = a > b ? a : b;
System.out.println("最大值为:" + max);
// 三个数最大值
int c = 10;
int tempMax = a > b ? a : b;
int max3 = tempMax > c ? tempMax : c;
System.out.println("最大值为:" + max3);
运算符优先级与括号
作用/概念简述
- 通过小括号明确计算顺序,避免优先级错误。
通用模版
System.out.println( (a > b || a < b) && a > b );
System.out.println( a > b || (a < b && a > b) );
属性/知识点表格
建议 | 说明 |
---|---|
使用括号 | 提高可读性,规避优先级记忆成本 |
片段代码案例
int a = 10, b = 20;
System.out.println((a > b || a < b) && a > b);
System.out.println(a > b || (a < b && a > b));
Scanner 键盘录入
作用/概念简述
- 从命令行读取用户输入。步骤:导包、创建对象、调用方法。
通用模版
import java.util.Scanner;
Scanner sc = new Scanner(System.in);
int age = sc.nextInt();
String name = sc.next();
属性/知识点表格
方法 | 作用 |
---|---|
nextInt() | 读整数 |
next() | 读字符串(到空白为止) |
片段代码案例
import java.util.Scanner;
public class ScannerDemo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入您的年龄: ");
int age = sc.nextInt();
System.out.println("请输入您的姓名: ");
String name = sc.next();
System.out.println("姓名为" + name + ", 年龄为" + age);
}
}
package 包管理
作用/概念简述
- 使用包组织类文件,分类管理,避免类名冲突。命名规则:公司域名倒序 + 模块名。
通用模版
package com.itheima.scanner;
public class ScannerDemo { }
属性/知识点表格
概念 | 说明 |
---|---|
包名 | com.itheima.xxx |
物理结构 | 多级目录对应包层级 |
片段代码案例
package com.itheima.test;
public class Hello {
public static void main(String[] args) {
System.out.println("Hello Package");
}
}
方法:无参无返回
作用/概念简述
- 将功能代码封装为方法,调用时执行,便于复用。
通用模版
public static void 方法名(){
// 方法体
}
方法名(); // 调用
属性/知识点表格
关键点 | 说明 |
---|---|
不调用不执行 | 方法需在 main 或其他方法中调用 |
平级关系 | 方法之间不能嵌套定义 |
片段代码案例
public class MethodTest {
public static void main(String[] args) {
getMax();
}
public static void getMax(){
int a = 10, b = 20;
System.out.println("最大值为:" + (a > b ? a : b));
}
}
带参数方法
作用/概念简述
- 通过参数让方法处理不同数据。形参:定义时;实参:调用时传入。
通用模版
public static void 方法名(类型 参数1, 类型 参数2){ }
方法名(实参1, 实参2);
属性/知识点表格
概念 | 说明 |
---|---|
形参 | 方法定义处,接收数据 |
实参 | 方法调用处,传入数据 |
片段代码案例
public static void printUserInfo(String name, int age, double height, char gender) {
System.out.println("姓名为:" + name);
System.out.println("年龄为:" + age);
System.out.println("身高为:" + height);
System.out.println("性别为:" + gender);
}
带返回值方法
作用/概念简述
- 将运算结果返回给调用者使用。return 结束方法并返回值。
通用模版
public static 返回类型 方法名(参数列表){
return 值;
}
返回类型 变量 = 方法名(实参);
属性/知识点表格
要点 | 说明 |
---|---|
返回类型 | 与 return 值类型一致 |
return | 结束当前方法 |
片段代码案例
public static int getMax(int a, int b){
int max = a > b ? a : b;
return max;
}
public static double getSum(double x, double y){
return x + y;
}
public static int getMin(int n1, int n2, int n3){
int t = n1 < n2 ? n1 : n2;
return t < n3 ? t : n3;
}
方法重载
作用/概念简述
- 同一类中,同名方法参数列表不同(个数/类型/顺序),与返回值无关。
通用模版
public static int add(int a, int b){ return a + b; }
public static double add(double a, double b){ return a + b; }
public static int add(int a, int b, int c){ return a + b + c; }
属性/知识点表格
匹配规则 | 说明 |
---|---|
参数不同 | 个数/类型/顺序 |
返回值无关 | 不能仅靠返回值区分 |
片段代码案例
System.out.println(add(1, 2)); // 调用 int 版本
System.out.println(add(1.1, 2.2)); // 调用 double 版本
System.out.println(add(1, 2, 3)); // 调用 3参版本
流程控制语句
理论篇
-
流程控制简介
- 定义:通过特定语句控制程序执行路径。
- 分类:
- 顺序结构:从上到下依次执行。
- 分支结构:if、switch(按条件选择分支执行)。
- 循环结构:for、while、do...while(重复执行)。
- 常见场景:
- if:区间判断、复杂条件组合。
- switch:等值判断(值固定、分支多时更清晰)。
-
if 语句
- 三种格式:
- 单分支:if (条件) {语句}
- 双分支:if (条件) {语句1} else {语句2}
- 多分支:if...else if...else...
- 使用场景:根据条件是否成立选择执行代码块。
- 注意事项:
- 条件必须产生 boolean 结果。
- ( ) 和 { } 之间不要加分号。
- 大括号可省(不建议,易读性差)。
- 三种格式:
-
switch 语句
- 语法:switch (表达式) { case 值: 语句; break; ... default: 语句; }
- 匹配:表达式依次和 case 值比较,命中即执行,通常用 break 终止。
- default:都未命中时执行。
- 合并分支:case 3: case 4: case 5: 表示同一分支(JDK14+ 支持 case 3,4,5 写法)。
- 适用场景:分支较多、等值判断(如 1-7 表示星期)。
-
循环(for / while / do...while)
- for:已知循环次数时常用;结构紧凑(初始化;条件;迭代)。
- while:未知次数时常用(条件为真继续);须在循环体内更新条件。
- do...while:至少执行一次(先执行再判断)。
- 嵌套循环:外层控制“行”,内层控制“列”,外循环一次,内循环跑一圈。
- 常见模式:
- 计数器:用于统计个数 count++。
- 累加器:用于求和 sum += x。
-
break / continue
- break:结束当前循环或 switch。
- continue:跳过本次循环,进入下一次。
- 嵌套循环:默认作用于最近的内层循环;可通过标号(label)定向作用。
-
Debug 工具(IDEA)
- 断点:定位可疑代码行。
- 单步执行:Step Over(逐行执行)、Step Into(进入方法)、Step Out(跳出方法)。
- 变量观察:查看变量值变化。
- 条件断点:断点处右键设置条件,仅在满足时中断。
- 用途:定位逻辑错误、验证循环与分支执行路径。
-
随机数 Random
- Random r = new Random();
- r.nextInt(n):返回 [0, n) 的随机整数。
- 常用区间转换:[a, b] = r.nextInt(b - a + 1) + a。
- 典型:猜数字游戏(综合 if、循环、Scanner、Random)。
代码篇
if 语句(单/双/多分支)
作用/概念简述
- 根据条件布尔值选择执行路径,支持单分支、双分支、多分支。
通用模版
if (条件) {
// 分支A
} else if (条件2) {
// 分支B
} else {
// 其他情况
}
属性/知识点表格
- 条件必须是 boolean 结果
- else if 可有多个
- 常用于区间、范围判断
片段代码案例
int score = 92;
if (score < 0 || score > 100) {
System.out.println("成绩有误");
} else if (score >= 95) {
System.out.println("奖励自行车一辆");
} else if (score >= 90) {
System.out.println("游乐场玩一次");
} else if (score >= 80) {
System.out.println("变形金刚玩具一个");
} else {
System.out.println("爱的教育");
}
switch 语句(含多 case 合并)
作用/概念简述
- 对表达式做等值匹配,命中 case 执行对应分支;适合“值枚举型”判断。
通用模版
switch (表达式) {
case 值1:
// 语句1
break;
case 值2:
// 语句2
break;
default:
// 语句n
break;
}
属性/知识点表格
- default 可选(建议补充)
- 无 break 会贯穿执行
- 多个 case 共用:case 3: case 4: case 5:
片段代码案例
int week = 6;
switch (week) {
case 1: System.out.println("星期一"); break;
case 2: System.out.println("星期二"); break;
case 3: System.out.println("星期三"); break;
case 4: System.out.println("星期四"); break;
case 5: System.out.println("星期五"); break;
case 6: System.out.println("星期六"); break;
case 7: System.out.println("星期日"); break;
default: System.out.println("您的输入有误"); break;
}
// 季节(JDK14+ 支持 case 3,4,5 写法)
int month = 6;
switch (month) {
case 3, 4, 5 -> System.out.println("春季");
case 6, 7, 8 -> System.out.println("夏季");
case 9, 10, 11 -> System.out.println("秋季");
case 12, 1, 2 -> System.out.println("冬季");
default -> System.out.println("输入有误");
}
for 循环(计次/倒序/模板)
作用/概念简述
- 已知次数循环,紧凑的“初始化-条件-迭代”结构。
通用模版
for (初始化; 条件; 迭代) {
// 循环体
}
属性/知识点表格
- 初始化:仅执行一次
- 条件:false 终止
- 迭代:每轮末执行
片段代码案例
// 跑三圈
for (int i = 1; i <= 3; i++) {
System.out.println("跑圈");
}
// 倒计时
for (int i = 10; i >= 1; i--) {
System.out.println("倒计时:" + i + "秒");
}
while 循环(未知次数)
作用/概念简述
- 条件为真重复执行,适合未知次数场景(循环体内注意更新条件)。
通用模版
初始化;
while (条件) {
// 循环体
迭代;
}
属性/知识点表格
- 条件判断在前
- 可能一次不执行
- 注意防止死循环
片段代码案例
// HelloWorld 打印5次
int i = 1;
while (i <= 5) {
System.out.println("HelloWorld");
i++;
}
do...while 循环(至少一次)
作用/概念简述
- 先执行后判断,循环体至少执行一次。
通用模版
初始化;
do {
// 循环体
迭代;
} while (条件);
属性/知识点表格
- 先执行后判断
- 至少执行一次
片段代码案例
int i = 1;
do {
System.out.println("Hello");
i++;
} while (i <= 3);
嵌套循环(矩形与三角形)
作用/概念简述
- 外层控制“行数”,内层控制“列数”;外层一次,内层跑一圈。
通用模版
for (int i = 1; i <= 行; i++) {
for (int j = 1; j <= 列; j++) {
// 内层输出
}
System.out.println();
}
属性/知识点表格
- 内层循环相当于外层每次的“任务”
- 打印图形常用
片段代码案例
// 5行10列矩形
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 10; j++) {
System.out.print("*");
}
System.out.println();
}
// 右下直角三角形
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
System.out.println();
}
计数器 / 累加器(模式模板)
作用/概念简述
- 计数器:count 统计次数
- 累加器:sum 累加求和
通用模版
// 计数器
int count = 0;
for (...) {
if (满足条件) count++;
}
// 累加器
int sum = 0;
for (...) {
sum += 值;
}
属性/知识点表格
- count 初值 0
- sum 初值 0
- 放在循环外定义,循环内更新
片段代码案例
// 1~100 偶数和
int sum = 0;
for (int i = 2; i <= 100; i += 2) {
sum += i;
}
System.out.println("偶数和 = " + sum);
数位拆分与水仙花数
作用/概念简述
- 利用 % 和 / 拆分“个位、十位、百位”;用于判断水仙花数(3位数,各位立方和等于其本身)。
通用模版
int ge = n % 10;
int shi = n / 10 % 10;
int bai = n / 100;
属性/知识点表格
- 个位:n % 10
- 十位:n / 10 % 10
- 百位:n / 100(3位数)
片段代码案例
// 打印所有水仙花数 & 统计个数
int count = 0;
for (int i = 100; i <= 999; i++) {
int ge = i % 10;
int shi = i / 10 % 10;
int bai = i / 100;
if (ge*ge*ge + shi*shi*shi + bai*bai*bai == i) {
System.out.println(i);
count++;
}
}
System.out.println("水仙花数个数:" + count);
break 与 continue(含标号)
作用/概念简述
- break:结束当前循环(或 switch)
- continue:跳过本次循环,继续下一次
- 嵌套定向:通过标号(label)作用于指定的循环
通用模版
// break/continue 基础
for (...) {
if (条件) break;
if (条件) continue;
}
// 标号
outer:
for (...) {
for (...) {
if (条件) break outer;
}
}
属性/知识点表格
- 默认作用最近的循环
- 标号:标识要跳出的循环
片段代码案例
// 基础
for (int i = 7; i <= 12; i++) {
if (i == 10) break;
System.out.println(i + "点正在学习");
}
// 带标号
outer:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (j == 2) break outer;
System.out.println(i + "-" + j);
}
}
Random 生成随机数(区间模板)
作用/概念简述
- 生成指定范围的随机整数,用于抽奖、猜数等。
通用模版
import java.util.Random;
// [0, n)
int x = new Random().nextInt(n);
// [a, b]
int y = new Random().nextInt(b - a + 1) + a;
属性/知识点表格
- [0, n):左闭右开
- [a, b]:加偏移
片段代码案例
Random r = new Random();
int n1 = r.nextInt(10); // [0,9]
int n2 = r.nextInt(100) + 1; // [1,100]
猜数字游戏(综合应用)
作用/概念简述
- 结合 Random、Scanner、while 与 if,进行人机交互小游戏。
通用模版
Random r = new Random();
Scanner sc = new Scanner(System.in);
int target = r.nextInt(100) + 1;
while (true) {
int guess = sc.nextInt();
// 比较并提示
}
属性/知识点表格
- 循环直到猜中(break)
- 提示大/小
- 读取输入并校验
片段代码案例
import java.util.Random;
import java.util.Scanner;
public class GuessNumber {
public static void main(String[] args) {
Random r = new Random();
Scanner sc = new Scanner(System.in);
int target = r.nextInt(100) + 1;
while (true) {
System.out.print("请输入(1~100):");
int input = sc.nextInt();
if (input > target) {
System.out.println("猜大了!");
} else if (input < target) {
System.out.println("猜小了!");
} else {
System.out.println("恭喜, 猜中了!");
break;
}
}
}
}
Debug 使用(断点/单步/条件断点)
作用/概念简述
- 借助调试工具逐步验证程序执行路径与变量值,定位逻辑问题。
通用模版
- 操作步骤:
- 在关键行设置断点(行号左侧点击)。
- Debug 运行程序(绿色小甲虫)。
- 常用控制:
- Step Over(F8):逐行执行。
- Step Into(F7):进入方法内部。
- Step Out(Shift+F8):跳出当前方法。
- 变量窗口观察值变化。
- 条件断点:断点右键设置“Condition”,仅条件成立时中断。
属性/知识点表格
- 断点位置要“有执行意义”的代码行
- 循环与分支处是常见断点点位
- 条件断点适合大型循环筛选中断
片段代码案例
public class DebugDemo {
public static void main(String[] args) {
int sum = 0; // 断点1:观察 sum 初值
for (int i = 1; i <= 5; i++) {
sum += i; // 断点2:观察每轮 i 和 sum
}
System.out.println(sum); // 断点3:查看最终结果
}
}
数组
理论篇
-
数组概念与优势
- 数组是一种“同类型多个数据的顺序存储容器”,可把零散数据集中管理。
- 适用场景:需要统一处理一组相同类型数据(遍历、统计、查找等)。
-
定义与初始化
- 定义格式:
- 数据类型[] 数组名;
- 数据类型 数组名[];(不推荐)
- 注意:上面仅是声明数组变量,并未创建容器。
- 静态初始化(已知元素):
- 数据类型[] 数组名 = new 数据类型[]{e1, e2, ...};
- 数据类型[] 数组名 = {e1, e2, ...};
- 动态初始化(已知长度):
- 数据类型[] 数组名 = new 数据类型[长度];
- 系统分配默认初始值:
- 整数:0;小数:0.0;布尔:false;字符:'\u0000';引用:null
- 定义格式:
-
元素访问与长度
- 访问:数组名[索引];索引从0开始,依次递增。
- 长度属性:数组名.length
- 常用:首个元素 arr[0],最后一个元素 arr[arr.length - 1]
-
遍历
- 经典 for:for (int i = 0; i < arr.length; i++) { ... }
- 快捷模板(IDEA):数组名.fori + 回车
-
常见数组综合操作
- 求偶数和(sum 累加器模式)
- 求最大值(假定首元素为初值 max,并更新)
- 数组反转(首尾双指针交换)
-
初始化选择
- 静态初始化:数据已知,直接列出元素。
- 动态初始化:数据未知,仅知道长度(比如随机生成数据后再处理)。
-
内存与参数传递
- 内存区域(关注点):栈(局部变量/方法栈帧)、堆(new 出来的对象/数组,存放数据,返回引用地址)、方法区(类元信息)。
- 参数传递:
- 基本类型:按值传递(拷贝值),方法内修改不影响外部变量。
- 引用类型:按值传递的是“地址值”,方法内通过地址可修改堆中数据,影响外部可见内容。
-
常见异常
- 数组索引越界(IndexOutOfBoundsException):访问了不存在的索引(如 i <= arr.length)。
- 空指针(NullPointerException):引用为 null 仍然通过引用访问元素。
-
二维数组
- 二维数组是“存放一维数组的容器”。
- 定义与初始化:
- int[][] arr = { {11,22,33}, {44,55,66} };
- 访问:arr[行索引][列索引]
- 遍历:外层遍历行(每个一维数组),内层遍历列(该行的每个元素)
- 提示:实际工作中二维数组使用较少,更常用“集合 + 对象”结构,二维数组主要用于了解与演示。
代码篇
数组定义与静态初始化
作用/概念简述
- 声明数组变量并一次性用已知元素创建数组容器。
通用模版
// 声明 + 静态初始化
数据类型[] 数组名 = {元素1, 元素2, 元素3};
// 或
数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, 元素3};
属性/知识点表格
- 声明不创建容器,初始化才创建
- 静态初始化不写长度,由系统计算
片段代码案例
int[] arr = {11, 22, 33, 44, 55};
System.out.println(arr[0]); // 11
System.out.println(arr[arr.length-1]); // 55
动态初始化与默认值
作用/概念简述
- 仅指定长度,元素值由系统设定默认值,后续再逐步赋值。
通用模版
数据类型[] 数组名 = new 数据类型[长度];
属性/知识点表格
类型 | 默认值 |
---|---|
整型 | 0 |
浮点 | 0.0 |
布尔 | false |
字符 | '\u0000'(空白) |
引用 | null |
片段代码案例
String[] names = new String[3];
for (int i = 0; i < names.length; i++) {
System.out.println(names[i]); // null, null, null
}
元素访问与 length
作用/概念简述
- 通过索引读写元素;通过 length 获取数组有效长度。
通用模版
数组名[索引] // 读取
数组名[索引] = 值; // 写入
数组名.length // 长度
属性/知识点表格
- 索引范围:[0, length-1]
- 最后一个元素:arr[arr.length - 1]
片段代码案例
int[] arr = {11, 22, 33, 44, 55};
System.out.println(arr[1]); // 22
arr[0] = 66;
System.out.println(arr[0]); // 66
if (arr[2] % 2 == 0) {
System.out.println(arr[2] + "是偶数");
} else {
System.out.println(arr[2] + "是奇数");
}
for (int i = 1; i <= arr[arr.length - 1]; i++) {
System.out.println("HelloWorld");
}
遍历(通用 for 模板)
作用/概念简述
- 依次访问数组每一个元素,进行输出、统计等操作。
通用模版
for (int i = 0; i < 数组名.length; i++) {
// 数组名[i] 即每个元素
}
属性/知识点表格
- 经典 for;下标从 0 到 length-1
- IDEA 快捷:数组名.fori
片段代码案例
int[] arr = {11, 22, 33, 44, 55};
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
案例:从数组中求偶数和
作用/概念简述
- 遍历数组,筛选偶数并累加(sum 累加器模式)。
通用模版
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) sum += arr[i];
}
属性/知识点表格
- sum 初始值为 0
- 条件判断:arr[i] % 2 == 0
片段代码案例
public static int getEvenSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] % 2 == 0) {
sum += arr[i];
}
}
return sum;
}
案例:求最大值
作用/概念简述
- 假定首元素为最大值,遍历比较,更新最大值变量。
通用模版
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) max = arr[i];
}
属性/知识点表格
- 初值:arr[0]
- 从索引1开始比
片段代码案例
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
案例:数组反转(原地交换)
作用/概念简述
- 使用双指针从两端向中间移动,交换对称元素。
通用模版
for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
属性/知识点表格
- 临时变量 temp
- 条件:start < end
片段代码案例
public static void reverseArray(int[] arr) {
for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
}
案例:随机生成 + 求最大值(动态初始化应用)
作用/概念简述
- 动态初始化数组,填充随机数并求最大值。
通用模版
Random r = new Random();
int[] arr = new int[n];
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(100) + 1; // [1,100]
}
int max = arr[0]; // 再遍历求最大值
属性/知识点表格
- 随机区间:[1,100] → nextInt(100)+1
- max 初值 arr[0]
片段代码案例
import java.util.Random;
public class ArrayRandomMax {
public static void main(String[] args) {
Random r = new Random();
int[] arr = new int[10];
System.out.println("产生的10个随机数为:");
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(100) + 1;
System.out.println(arr[i]);
}
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
}
System.out.println("最大值为: " + max);
}
}
综合案例:评委打分(去掉最高最低后平均)
作用/概念简述
- 录入 6 个分数,求和、取最大最小,去掉最高与最低后求平均值。
通用模版
int[] arr = initData(); // 读取输入并校验
int sum = getSum(arr);
int max = getMax(arr);
int min = getMin(arr);
double avg = (sum - max - min) * 1.0 / (arr.length - 2);
属性/知识点表格
- 数据校验:0~100
- 平均:double 参与运算避免整除
片段代码案例
import java.util.Scanner;
public class JudgeScore {
public static void main(String[] args) {
int[] arr = initData();
int sum = getSum(arr);
int max = getMax(arr);
int min = getMin(arr);
double avg = (sum - max - min) * 1.0 / (arr.length - 2);
System.out.println("平均值为: " + avg);
}
public static int[] initData() {
Scanner sc = new Scanner(System.in);
int[] arr = new int[6];
System.out.println("请输入6个评委的分数:");
for (int i = 0; i < arr.length; i++) {
System.out.print("第" + (i + 1) + "个: ");
int score = sc.nextInt();
if (score >= 0 && score <= 100) {
arr[i] = score;
} else {
System.out.println("输入有误, 请重新输入0~100之间的分数");
i--;
}
}
return arr;
}
public static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) sum += arr[i];
return sum;
}
public static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) if (arr[i] > max) max = arr[i];
return max;
}
public static int getMin(int[] arr) {
int min = arr[0];
for (int i = 1; i < arr.length; i++) if (arr[i] < min) min = arr[i];
return min;
}
}
参数传递:基本类型 vs 引用类型
作用/概念简述
- 基本类型:传值(方法内改不回去)
- 引用类型:传地址(方法内可改动堆中数据)
通用模版
// 基本类型
public static void change(int number) { number = 200; }
// 引用类型
public static void change(int[] arr) { arr[0] = 66; }
属性/知识点表格
- 基本类型:想要“生效”,需 return 新值
- 引用类型:直接改数组元素即可反映到调用方
片段代码案例
public class ArgsPassDemo {
public static void main(String[] args) {
int num = 100;
change(num);
System.out.println(num); // 100
int[] arr = {11, 22, 33};
change(arr);
System.out.println(arr[0]); // 66
}
public static void change(int number) { number = 200; }
public static void change(int[] arr) { arr[0] = 66; }
}
常见异常案例:索引越界与空指针
作用/概念简述
- 越界:访问无效下标
- 空指针:引用为 null 时访问元素
通用模版
// 越界
System.out.println(arr[arr.length]); // 错
// 空指针
arr = null;
System.out.println(arr[0]); // 错
属性/知识点表格
- 有效索引:0 ~ length-1
- 访问前判断:if (arr != null) { ... }
片段代码案例
public class ExceptionDemo {
public static void main(String[] args) {
int[] arr = {11, 22, 33};
// System.out.println(arr[10]); // IndexOutOfBoundsException
// for (int i = 0; i <= arr.length; i++) System.out.println(arr[i]); // 错误:<=
arr = null;
// System.out.println(arr[0]); // NullPointerException
}
}
二维数组:定义与访问
作用/概念简述
- 存放“一维数组”的容器,按“行-列”访问。
通用模版
int[][] arr = {
{11, 22, 33},
{44, 55, 66}
};
int x = arr[0][2]; // 33
属性/知识点表格
- arr.length:行数
- arr[i].length:第 i 行的列数
片段代码案例
public class Array2DDemo {
public static void main(String[] args) {
int[][] arr = {
{11, 22, 33},
{44, 55, 66}
};
System.out.println(arr[0][2]); // 33
System.out.println(arr[1][1]); // 55
}
}
二维数组遍历
作用/概念简述
- 外层遍历行,内层遍历每行的列。
通用模版
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
// arr[i][j]
}
}
属性/知识点表格
- 每行长度可能不同(非规则矩阵时)
片段代码案例
public class Array2DTraverse {
public static void main(String[] args) {
int[][] arr = {
{11, 22, 33},
{44, 55, 66}
};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.println(arr[i][j]);
}
}
}
}
面向对象基础
理论篇
-
面向对象思想
- 核心:用“对象”来抽象现实中的事物,通过对象之间的交互协作解决问题。
- 好处:贴近生活思维、可读性强、可复用、易维护。
- 关键点:
- 自己设计对象(类)→ 企业开发常态;
- 使用已有对象(API)→ 在后续 API 章节扩展。
-
类与对象
- 类:一组“属性(名词)+ 行为(动词)”的集合,是对象的“设计图”。
- 对象:根据类创建出来的实体,具有具体的数据与能力。
- 关系:
- 依赖关系:new 类名() 才能得到对象。
- 数量关系:一个类可创建多个对象(独立互不影响)。
-
成员与方法
- 成员变量(属性):描述事物状态,定义在类中(方法外),有默认值,存在于堆内存。
- 成员方法(行为):描述事物能力,定义在类中,默认无 static(对象方法)。
- 使用方式:对象.变量名;对象.方法名();
-
内存模型(简化理解)
- 栈:存放方法栈帧、局部变量(包含对象引用/地址)。
- 堆:存放通过 new 创建的对象与数组(真正数据存储处)。
- 方法区:类的元数据(字节码、常量等)。
- 读图思维:
- Student stu = new Student():栈上有 stu 引用,堆上有 Student 对象,stu 保存的是对象的地址。
-
成员变量 vs 局部变量
- 位置:成员在类中方法外;局部在方法/代码块/形参列表中。
- 默认值:成员有默认值;局部无默认值,使用前必须赋值。
- 内存:成员在堆;局部在栈。
- 生命周期:成员随对象→从创建到回收;局部随方法→从调用到结束。
- 作用域:都受 {} 限制。
-
this 关键字
- 含义:当前对象的引用(地址)。
- 作用:
- 访问成员:this.成员变量、this.成员方法()
- 解决重名:当局部变量与成员变量重名时,用 this 区分成员变量。
- 省略规则:
- 不涉及重名时 this 可省略;
- 方法调用时 this.也常省略(默认调用当前对象的方法)。
-
构造方法(构造器)
- 作用:创建对象时被调用(每次 new 都会调用),可用于在创建对象时初始化成员变量。
- 特点:方法名与类名相同,无返回类型(连 void 也不写),可重载(参数列表不同)。
- 若未显式声明,系统提供无参构造;一旦自定义了构造方法,默认无参构造不再自动生成(需手写补上)。
-
封装与访问控制
- 封装思想:对外隐藏内部实现细节,仅暴露必要的对外接口(如汽车封装了零部件,仅暴露方向盘/油门等)。
- 权限修饰符:
- private:仅当前类
- 默认(包访问):同包内可访问
- protected:同包内、不同包的子类
- public:任意位置
- 规范:合理隐藏(private),合理暴露(public)。
-
标准 JavaBean(实体类)
- 定义:仅封装数据,处理逻辑交由其他类负责(数据与业务分离)。
- 标准:
- 成员变量 private;
- 提供 public 的 getter/setter;
- 提供无参构造与全参构造。
-
static(静态)
- 含义:属于类本身,类加载即存在,所有对象共享。
- 使用:
- 静态变量:共享属性(如计数器)
- 静态方法:工具类方法或与实例无关的操作(类名.方法() 直接调用)
- 注意:
- 静态方法中不能直接访问非静态成员(非静态成员需要对象);
- 静态方法中不能使用 this(this 代表当前对象)。
-
工具类与文档注释
- 工具类:通过 static 方法对外提供便捷服务(如数组工具类、字符串工具类),通常私有构造防止被实例化。
- 文档注释:使用 /** */ 提供描述、参数与返回说明,可生成 JavaDoc 帮助文档。
-
main 方法再认识
- public static void main(String[] args)
- 程序入口;静态→无需创建对象即可执行;args → 命令行参数数组。
- public static void main(String[] args)
代码篇
类与对象:定义、创建与使用
作用/概念简述
- 定义类(属性+行为),通过 new 创建对象,使用对象进行读写与方法调用。
通用模板
// 类(设计图)
public class ClassName {
// 成员变量(属性)
类型 名称;
// 成员方法(行为)
public void 方法名() { ... }
}
// 创建使用
ClassName obj = new ClassName();
obj.名称 = 值;
obj.方法名();
属性/知识点表格
- 对象访问:对象.变量/方法
- 多个对象互不影响
- 成员变量有默认值
片段代码案例
public class Student {
String name;
int age;
public void study() {
System.out.println(name + " 在学习Java");
}
public void eat() {
System.out.println(name + " 吃饭");
}
}
public class StudentTest {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.name = "张三";
stu1.age = 23;
stu1.study();
stu1.eat();
Student stu2 = new Student();
stu2.name = "李四";
stu2.age = 24;
stu2.study();
}
}
this:区分重名与调用成员
作用/概念简述
- 当前对象引用;在成员与局部变量同名时用 this 区分访问成员变量。
通用模板
public class Person {
String name;
public void sayHello(String name) {
System.out.println("局部变量:" + name);
System.out.println("成员变量:" + this.name);
}
}
属性/知识点表格
- this 可省略(不重名时)
- this 不可用于静态上下文
片段代码案例
Person p = new Person();
p.name = "成员张三";
p.sayHello("局部李四");
// 输出:局部李四 / 成员张三
构造方法:初始化对象
作用/概念简述
- 创建对象时调用,初始化成员变量,可重载。
通用模板
public class Student {
String name;
int age;
// 无参构造
public Student() {}
// 全参构造
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
// 使用
Student stu1 = new Student("张三", 23);
Student stu2 = new Student();
stu2.name = "李四";
stu2.age = 24;
属性/知识点表格
- 方法名同类名
- 无返回类型
- 构造与 new 绑定执行
封装:隐藏实现与对外接口
作用/概念简述
- 使用 private 隐藏成员,通过 public 方法对外暴露必要功能。
通用模板
public class Phone {
private String brand;
private int price;
// 对外接口
public void call(String name) {
saveLog(name);
System.out.println("给 " + name + " 打电话");
}
// 内部使用
private void saveLog(String name) {
System.out.println("保存通话记录:" + name);
}
}
属性/知识点表格
- private:仅当前类可访问
- public:对外暴露
标准 JavaBean:数据封装类
作用/概念简述
- 仅承载数据,提供 getter/setter 与构造,常存放于 pojo 包中。
通用模板
public class Student {
private String name;
private int age;
public Student() { }
public Student(String name, int age) {
this.name = name; this.age = age;
}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
属性/知识点表格
- 成员私有
- 提供无参+全参构造
- 提供 getter/setter
static:类成员与工具类
作用/概念简述
- 静态成员属于类共享,工具类方法常用 static 提供便捷调用。
通用模板
public class Counter {
public static int total = 0; // 静态变量
public static void add(int x) { // 静态方法
total += x;
}
}
public class ArrayTools {
private ArrayTools(){}
public static int getMax(int[] arr){
int max = arr[0];
for(int i=1;i<arr.length;i++){
if(arr[i]>max) max = arr[i];
}
return max;
}
}
属性/知识点表格
- 静态方法中不能直接访问非静态成员
- 静态方法中不能使用 this
- 工具类私有构造,禁止实例化
片段代码案例
int[] data = {11,22,33,44};
int max = ArrayTools.getMax(data);
System.out.println(max);
Counter.add(5);
Counter.add(10);
System.out.println(Counter.total); // 15
权限修饰符:可见性控制
作用/概念简述
- 控制类/成员对外可见范围。
通用模板
- private:类内
- 默认(不写):同包
- protected:同包或不同包的子类
- public:任意位置
属性/知识点表格
- 封装推荐:属性 private + public getter/setter
- 方法对外暴露尽量最小
片段代码案例
public class Demo {
private int secret = 100; // 仅本类可见
public void print(){ System.out.println(secret); }
}
main 方法:程序入口
作用/概念简述
- Java 程序入口,静态方法,不依赖对象。
通用模板
public class App {
public static void main(String[] args) {
// args 即命令行参数
System.out.println("Hello OOP");
}
}
属性/知识点表格
- public:JVM 可访问
- static:无需对象
- String[]:接收参数
面向对象高级
理论篇
-
继承与重写总览
- 继承:子类复用父类非私有成员,提升复用与维护性,但增强耦合。
- 成员变量访问冲突:同名时,this 访问本类,super 访问父类。
- 方法重写(Override):子类对父类方法“声明完全一致”的重新实现。调用时“编译看左边,运行看右边”。
-
权限与 protected
- 访问级别(从小到大):private < 默认(包内) < protected(包内+不同包子类) < public。
- protected:常用于父类成员对子类开放访问(不同包的子类可见)。
-
构造方法与初始化顺序
- 构造不能继承;子类构造前需先完成父类初始化。
- 每个构造器第一行默认 super();可显式 super(参数) 调父类有参。
- this() 与 super() 不能共存于同一构造器首行。
-
this 与 super
- this:当前对象的引用。访问本类成员变量/方法;this() 调本类其它构造器。
- super:父类空间的引用。访问父类成员变量/方法;super() 调父类构造。
-
Object 类常用方法
- toString:默认“全类名@哈希十六进制”。建议重写,便于日志与调试。
- equals:默认比较地址。重写以比较“内容”(注意类型判断与空指针)。
-
final 关键字
- 修饰类:不可继承;修饰方法:不可重写;修饰变量:常量(必须初始化),引用常量不可再指向其他对象(但对象内容可改)。
-
抽象类与模板方法
- 抽象类:包含抽象方法(无方法体)与普通方法的“特殊父类”,不能实例化,构造器用于子类初始化。
- 设计意图:抽象公共行为,强制子类重写不可确定部分。
- 模板方法:在父类定义“算法骨架”,可变部分抽象,子类按需实现(模板 + 抽象方法)。
-
接口
- 本质:规则/契约(默认抽象方法)。类与接口是“实现关系”(implements)。
- 接口成员(JDK8+):常量(public static final),抽象方法(public abstract),默认方法(default,可被实现类继承或重写),静态方法(接口名.静态方法() 调用),JDK9+ 私有方法(接口内部复用)。
- 多实现:类可实现多个接口;接口间可多继承(extends A,B)。
-
抽象类 vs 接口
- 抽象类:对“事物”抽象,可含状态与部分实现;单继承。
- 接口:对“行为规则”抽象,可无状态;多实现。
- 应用建议:共性“类型”的抽象→抽象类;规则/能力扩展→接口。
-
多态(父类引用指向子类对象)
- 前提:继承/实现 + 方法重写 + 父类/接口类型接收子类对象。
- 访问特性:
- 成员变量:编译看左(父),运行看左(父)。
- 成员方法:编译看左(是否存在),运行看右(子类实现)。
- 静态方法:编译看左,运行看左(建议类名调用)。
- 优点:扩展性强(一个方法接收父类型,兼容多种子类)。
- 缺点:不能直接使用子类特有成员;需向下转型(有风险,配合 instanceof)。
-
代码块与包
- 局部代码块:限定变量作用域(方法中一对 {})。
- 构造代码块:每次 new 对象执行,优先于构造器(不常用)。
- 静态代码块:类加载时执行一次(常用于初始化一次性资源)。
- 包:组织类的目录结构(公司域名倒写.模块名)。import 冲突时需全限定名。
-
内部类与匿名内部类
- 成员内部类:外部类.内部类 对象 = new 外部类().new 内部类();内部类可直接访问外部类成员,外部类需创建内部类对象访问。
- 静态内部类:外部类.内部类 对象 = new 外部类.内部类();可有静态成员。
- 局部内部类:方法内定义(较少用)。
- 匿名内部类:定义类 + 实例一次性合并,常用于方法实参(临时实现某接口/子类)。
-
Lambda 表达式(JDK8+)
- 作用:简化“匿名内部类实现函数式接口”的写法。
- 函数式接口:仅有一个抽象方法(@FunctionalInterface 标记)。
- 语法:() -> { 方法体 }。可省略参数类型、单参括号、单语句大括号与 return(有返回值时)。
代码篇
继承与成员访问
作用/概念简述
- 提升复用;演示 this/super 访问冲突与成员覆盖。
通用模板
class Employee {
private String name; private int age; private double salary;
public void work(){ System.out.println("员工工作"); }
// getter/setter 省略
}
class Coder extends Employee { }
class Manager extends Employee { }
属性/知识点卡
- 非私有成员子类可直接用;私有属性通过 getter/setter
片段代码案例
class A { int num = 10; }
class B extends A { int num = 20; void print(){ System.out.println(this.num); System.out.println(super.num); } }
new B().print(); // 20 / 10
方法重写 @Override
作用/概念简述
- 子类按相同声明(名/参/返回)重写父类方法,运行时绑定子类逻辑。
通用模板
class Father { void love(){ System.out.println("送花"); } }
class Son extends Father {
@Override
public void love(){
super.love();
System.out.println("送口红");
}
}
属性/知识点卡
- 访问权限可放大不可缩小;返回类型协变;不能抛出比父类更大的检查异常
protected 使用
作用/概念简述
- 包内均可见;不同包的子类可见(相对默认多加“不同包子类”)
通用模板
public class Base {
protected void show(){ System.out.println("Base.show"); }
}
package other;
public class Sub extends Base {
public void test(){ show(); } // 允许
}
构造器与 super/this
作用/概念简述
- 子类先初始化父类;super()/this() 必在构造首行,且不能同时出现。
通用模板
class Person { String name; int age; Person(){ } Person(String n,int a){ name=n; age=a; } }
class Student extends Person {
int score;
Student(){ super(); }
Student(String n,int a,int s){ super(n,a); this.score=s; }
}
属性/知识点卡
- 子类不写构造器,默认有无参并隐式 super();
- 构造器不能被继承
重写 toString / equals
作用/概念简述
- toString 友好展示;equals 比较内容。
通用模板
class Student {
private String name; private int age;
@Override public String toString(){ return "Student{name='" + name + "', age=" + age + "}"; }
@Override public boolean equals(Object o){
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student s = (Student) o;
return age == s.age && java.util.Objects.equals(name, s.name);
}
}
属性/知识点卡
- equals 重写配合 hashCode 一起(哈希集合场景);Objects.equals 防 NPE
final 关键字
作用/概念简述
- 限制继承/重写与再赋值;常量命名:全大写+下划线。
通用模板
final class Util { }
class A { final void m(){ } }
class B extends A { /* 不能重写 m */ }
final int MAX_COUNT = 100;
final int[] arr = {1,2}; arr[0]=9; // ok;arr = new int[2]; // error
抽象类与模板方法
作用/概念简述
- 抽象方法强制子类实现;模板方法固定流程,抽象点留给子类。
通用模板
abstract class Animal { public abstract void eat(); }
class Cat extends Animal { public void eat(){ System.out.println("猫吃鱼"); } }
abstract class TextTemplate {
public final void write(){
System.out.println("我的爸爸");
body();
System.out.println("啊~这就是我的爸爸!");
}
protected abstract void body();
}
class Tony extends TextTemplate {
protected void body(){ System.out.println("故事内容..."); }
}
接口:定义与实现
作用/概念简述
- 声明规则;类通过 implements 实现。
通用模板
interface Inter { void show(); default void hello(){ System.out.println("hello"); } static void info(){ System.out.println("info"); } }
class InterImpl implements Inter { public void show(){ System.out.println("实现类show"); } }
Inter i = new InterImpl(); i.show(); i.hello(); Inter.info();
属性/知识点卡
- 常量隐式 public static final;抽象方法隐式 public abstract;默认方法 default;静态方法接口名调用;私有方法接口内部复用(JDK9)
多态:前提与成员访问
作用/概念简述
- 父/接口类型接收子/实现类对象;运行期选择方法版本。
通用模板
class Fu { int num=10; public void show(){ System.out.println("Fu.show"); } public static void s(){ System.out.println("Fu.s"); } }
class Zi extends Fu { int num=20; public void show(){ System.out.println("Zi.show"); } public static void s(){ System.out.println("Zi.s"); } }
Fu f = new Zi();
System.out.println(f.num); // 10
f.show(); // Zi.show
f.s(); // Fu.s(建议 Fu.s())
属性/知识点卡
- 子类特有成员需向下转型;使用 instanceof 避免 ClassCastException
片段代码案例(向下转型)
Animal a = new Dog();
if (a instanceof Dog d) { d.watchHome(); }
订单多态案例(接口 + 实现切换)
作用/概念简述
- 通过接口抽象订单业务;运行时切换不同实现(国内/国外)。
通用模板
interface OrderService{ void create(); void findOne(); void findList(); void cancel(); void finish(); void paid(); }
class OrderServiceImpl implements OrderService { /* 国内实现(输出模拟) */ }
class OverseasServiceImpl implements OrderService { void check(){ System.out.println("IP检测"); } /* 国外实现 */ }
OrderService s = choice==1? new OrderServiceImpl() : new OverseasServiceImpl();
if (s instanceof OverseasServiceImpl o) o.check();
s.create(); s.findList(); // ...
代码块与包
作用/概念简述
- 静态代码块适合一次性初始化;包管理类并处理导入冲突。
通用模板
package com.itheima.demo;
class Student {
static { System.out.println("类加载初始化一次"); }
{ System.out.println("每次 new 前执行"); }
public Student(){ System.out.println("构造方法"); }
}
属性/知识点卡
- java.lang 包自动导入;同名类需全限定名;import xxx.* 导入该包所有类
内部类、匿名内部类与 Lambda
作用/概念简述
- 成员/静态/局部内部类用于紧密封装;匿名内部类临时实现;Lambda 简化函数式接口实现。
通用模板
// 成员内部类
class Outer {
private int num=10;
class Inner { void show(){ System.out.println(num); } }
}
Outer.Inner oi = new Outer().new Inner(); oi.show();
// 静态内部类
class Outer2{ static class Inner{ static void m(){ } void n(){ } } }
Outer2.Inner.m(); new Outer2.Inner().n();
// 匿名内部类
useInter(new Inter(){ public void show(){ System.out.println("匿名重写"); } });
// Lambda(函数式接口)
@FunctionalInterface interface ShowHandler{ void show(); }
useShowHandler(() -> System.out.println("Lambda 重写"));
属性/知识点卡
- Lambda 省略:参数类型可省;单参可省括号;单语句可省大括号与 return(有返回值时)
equals 与 Objects 工具
作用/概念简述
- Objects.equals(a,b) 避免空指针,底层调用 a.equals(b)。
通用模板
Person p1=null, p2=new Person("张三",23);
System.out.println(java.util.Objects.equals(p1,p2)); // false
常用 API
理论篇
-
API 与文档
- 概念:API 是别人写好的类与方法集合,直接调用即可完成常见功能(如 Scanner、Random、String、ArrayList 等)。
- 文档使用要点:
- 搜索类名,确认包(java.lang 无需导包,其它需要 import)。
- 读类说明(用途)、构造方法(如何创建对象)、成员方法(方法名、参数、返回值、备注)。
-
String 字符串
- 特点:
- 字符串字面量("abc")本质是 String 对象。
- 字符串不可变(修改等价于产生新对象)。
- 字符串常量池:相同字面量共用同一常量池对象("abc" 复用)。
- 创建方式:
- 字面量:"abc"(常量池)
- 构造:new String("abc") 或 new String(char[])(堆,独立对象)
- 面试要点:
- s1="abc"; s2="abc"; ⇒ s1==s2 为 true(同池对象)
- s1=new String("abc"); s2="abc"; ⇒ s1==s2 为 false(堆与池不同)
- 拼接规则:运行期拼接会用 StringBuilder;纯字面量拼接编译期常量折叠。
- 特点:
-
String 常用方法
- 比较:equals、equalsIgnoreCase(忽略大小写)
- 遍历:length、charAt、toCharArray
- 截取:substring(begin)、substring(begin,end)(包头不包尾)
- 替换:replace(old,new)(返回新串)
- 切割:split(regex)(正则,注意转义 "+" ⇒ "\+")
-
StringBuilder 与 StringBuffer
- StringBuilder:可变字符序列,非线程安全,性能高(推荐单线程)。
- StringBuffer:可变字符序列,线程安全(方法加锁),性能低于 StringBuilder(多线程场景)。
- 提升效率原理:在同一内存缓冲区修改,不频繁创建新对象。
- 常用方法:append(链式拼接)、reverse、length、toString。
-
集合(以 ArrayList 为例)
- 定义:可变长度的容器,解决数组长度固定问题。
- 与数组选择:
- 数组:元素个数固定、性能稳定(空间不浪费)。
- 集合:元素数量经常改变(底层动态扩容,可能产生空间浪费)。
- 泛型:限制集合元素类型(只能写引用类型,基本类型用包装类)。
- 常用方法:
- add(e)、add(index,e)
- remove(index)/remove(Object)
- set(index,e)
- get(index)、size()
-
遍历与修改
- 遍历时删除元素的两种安全写法:
- 正序遍历时删除后 i-- 回退索引
- 倒序遍历(从 size()-1 到 0)删除不影响未遍历元素
- 遍历时删除元素的两种安全写法:
代码篇
API 文档查阅通用模板
作用/概念简述
- 正确找到类、构造、方法并调用。
通用模板
1) 打开 API 文档,搜索类名(如 String、ArrayList)
2) 确认包名(java.lang.* 无需导包,其它需要 import)
3) 阅读类注释(用途)
4) 选构造方法创建对象
5) 查找成员方法(方法签名、参数、返回值、注意事项)
属性/知识点卡
点 | 要领 |
---|---|
包 | java.lang 无需导包 |
构造 | 确认如何 new 对象 |
方法 | 看参数类型、返回值、是否正则、是否新对象 |
String 创建与比较
作用/概念简述
- 理解常量池与不可变特性,正确比较内容。
通用模板
// 创建
String s1 = "abc"; // 常量池
String s2 = new String("abc"); // 堆
char[] chs = {'a','b','c'};
String s3 = new String(chs);
// 比较
System.out.println(s1.equals(s2)); // 内容比较(true)
System.out.println(s1 == s2); // 地址比较(false)
System.out.println("AbC".equalsIgnoreCase("aBc")); // true
属性/知识点卡
点 | 说明 |
---|---|
不可变 | 修改等价新对象 |
常量池 | 相同字面量复用 |
比较 | equals/equalsIgnoreCase 比内容,== 比地址 |
String 遍历与统计
作用/概念简述
- 统计字符串中的字符分类;两种遍历方式。
通用模板
String s = "aAb3&c2B*4CD1";
int lower=0, upper=0, digit=0;
// 方式一:toCharArray
for (char c : s.toCharArray()) {
if (c>='a' && c<='z') lower++;
else if (c>='A' && c<='Z') upper++;
else if (c>='0' && c<='9') digit++;
}
// 方式二:charAt
for (int i=0;i<s.length();i++){
char c = s.charAt(i);
// 同上判断
}
System.out.println(lower+" "+upper+" "+digit);
属性/知识点卡
方法 | 用途 |
---|---|
length | 长度 |
charAt(i) | 按索引取字符 |
toCharArray | 转字符数组 |
String 截取、替换、切割与脱敏
作用/概念简述
- 处理子串、敏感词替换、正则切割与手机号脱敏。
通用模板
String s = "itheima";
// 截取
String a = s.substring(0,2); // it
String b = s.substring(2); // heima
// 替换(返回新串)
String t = "hello TMD";
t = t.replace("TMD","***");
// 切割(正则)
String ip = "192+168+10+20";
String[] parts = ip.split("\\+");
// 手机号脱敏:156****1234
String tel = "15612341234";
String start = tel.substring(0,3);
String end = tel.substring(7);
String masked = start + "****" + end;
属性/知识点卡
方法 | 说明 |
---|---|
substring | 包头不包尾 |
replace | 返回新字符串 |
split | 正则规则,注意转义 |
String 登录练习
作用/概念简述
- equals 比较用户名/密码,三次机会。
通用模板
String user="admin", pass="1234";
Scanner sc = new Scanner(System.in);
for (int i=1;i<=3;i++){
String u=sc.next(), p=sc.next();
if (user.equals(u) && pass.equals(p)) { System.out.println("登录成功"); break; }
else System.out.println(i==3? "明儿再来吧!" : "登录失败, 您还剩余"+(3-i)+"次机会");
}
StringBuilder 基本用法与性能
作用/概念简述
- 可变字符序列,高效拼接、反转、转换。
通用模板
// 构造
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder("abc");
// 常用方法
sb1.append("红色").append("蓝色").append("绿色"); // 链式
int len = sb1.length();
sb1.reverse();
String s = sb1.toString();
// 性能测试
long t1=System.currentTimeMillis();
StringBuilder sb=new StringBuilder();
for(int i=1;i<=100000;i++) sb.append(i);
long t2=System.currentTimeMillis();
System.out.println("耗时: "+(t2-t1)+"ms");
属性/知识点卡
方法 | 说明 |
---|---|
append | 追加任意类型,返回自身 |
reverse | 反转 |
length | 长度 |
toString | 转回 String |
StringBuilder 案例
作用/概念简述
- 回文字符串判断;数组转指定格式字符串。
通用模板
// 回文
String content = "123321";
StringBuilder sb = new StringBuilder(content).reverse();
System.out.println(content.equals(sb.toString()) ? "是" : "不是");
// 数组拼接 [1, 2, 3]
public static String arrayToString(int[] arr){
if (arr==null || arr.length==0) return "[]";
StringBuilder sb = new StringBuilder("[");
for(int i=0;i<arr.length-1;i++){
sb.append(arr[i]).append(", ");
}
sb.append(arr[arr.length-1]).append("]");
return sb.toString();
}
属性/知识点卡
注意 | 说明 |
---|---|
判空 | null 或空数组返回 [] |
末尾逗号 | 最后一个元素单独处理 |
StringBuffer 特性
作用/概念简述
- 与 StringBuilder API 类似;线程安全;多线程场景使用。
属性/知识点卡
类 | 线程安全 | 性能 | 场景 |
---|---|---|---|
String | 不可变 | 低(拼接频繁) | 少量拼接/常量 |
StringBuilder | 否 | 高 | 单线程拼接 |
StringBuffer | 是 | 中 | 多线程拼接 |
ArrayList 创建与泛型
作用/概念简述
- 可变长度集合;使用泛型限定元素类型。
通用模板
import java.util.ArrayList;
ArrayList<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
ArrayList<Double> ds = new ArrayList<>();
ds.add(11.1); ds.add(22.2);
// 基本类型用包装类:Integer、Double、Boolean、Character...
属性/知识点卡
方法 | 说明 |
---|---|
add(e)/add(i,e) | 追加/插入 |
remove(i)/remove(o) | 按索引/按对象删 |
set(i,e) | 替换 |
get(i) | 取元素 |
size() | 元素个数 |
ArrayList 遍历与删除
作用/概念简述
- 遍历每一项,删除满足条件的元素(避免跳元素)。
通用模板
ArrayList<String> list = new ArrayList<>();
list.add("test"); list.add("张三"); list.add("test");
// 方案一:正序 + i--
for (int i=0;i<list.size();i++){
if ("test".equals(list.get(i))) {
list.remove(i);
i--;
}
}
// 方案二:倒序
for (int i=list.size()-1;i>=0;i--){
if ("test".equals(list.get(i))) list.remove(i);
}
属性/知识点卡
注意 | 说明 |
---|---|
删除后回退 | 正序删除需 i-- |
倒序删除 | 不受索引左移影响 |
ArrayList 操作学生对象
作用/概念简述
- 存储对象、筛选、键盘录入。
通用模板
// 对象列表与筛选
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("张三", 23));
list.add(new Student("李四", 14));
ArrayList<Student> result = new ArrayList<>();
for (int i=0;i<list.size();i++){
Student s = list.get(i);
if (s.getAge() < 18) result.add(s);
}
// 键盘录入添加
Scanner sc = new Scanner(System.in);
ArrayList<Student> all = new ArrayList<>();
for (int i=1;i<=3;i++){
System.out.println("第"+i+"个:");
String name = sc.next();
int age = sc.nextInt();
all.add(new Student(name, age));
}
属性/知识点卡
点 | 说明 |
---|---|
泛型 | 限定 Student 类型 |
迭代 | get(i) 逐个处理 |
设计 | 先封装对象再入集合 |
练习:过滤、打印指定条件
作用/概念简述
- 从集合中过滤符合某条件的元素到新集合。
通用模板
public static ArrayList<Student> filterList(ArrayList<Student> list){
ArrayList<Student> result = new ArrayList<>();
for (int i=0;i<list.size();i++){
Student s = list.get(i);
if (s.getAge() < 18) result.add(s);
}
return result;
}
属性/知识点卡
模式 | 说明 |
---|---|
过滤 | 新建 result,遍历判定、符合则 add |
商品管理系统(综合案例)
理论篇
-
案例目标与所用知识
- 目标:基于控制台实现一个可持续运行的商品管理系统(增删改查、查询单个、退出)。
- 综合运用:JavaBean 封装、集合 ArrayList、Scanner、循环与分支、方法拆分、静态代码块初始化、字符串比较 equals、工具方法复用。
-
系统功能清单
- 查看全部商品:遍历集合输出所有商品信息。
- 添加商品:键盘录入,封装对象入集合;校验商品编号唯一。
- 删除商品:根据编号查索引并删除;编号不存在提示。
- 修改商品:按编号查找并替换为新对象;编号不存在提示。
- 查询单个商品:按编号查找并输出;编号不存在提示。
- 退出系统:System.exit(0)。
-
核心数据模型与存储
- JavaBean:Goods(id、name、price、desc),封装字段,提供构造器、getter/setter、toString。
- 存储容器:ArrayList(动态数组,易增删改查)。
- 静态共享:将集合与 Scanner 定义为 static,便于 main 和静态方法直接使用。
-
业务流程与方法拆分
- 菜单循环 while(true) + switch 分发功能。
- 工具方法复用:getIndex(id) 统一提供通过编号查找索引(找不到返回 -1)。
- 业务方法建议:
- addGoods、deleteGoodsById、updateGoodsById、queryAllGoods、queryGoodsById。
- 静态代码块:初始化测试数据,程序启动即就绪。
-
数据校验与提示
- 编号唯一:添加前 while(getIndex(id) != -1) 循环提示重新输入。
- 输入错误提示:默认分支 default 给出“输入有误”并继续循环。
- 删除、修改、查询单个:索引判断 -1 → 统一提示“编号不存在”。
-
复杂度与可扩展性
- 当前查找复杂度 O(n):getIndex 顺序遍历;数据量不大时简单直观。
- 可扩展方向:
- 使用 HashMap<String, Goods> 降低为 O(1) 查找。
- 分层重构:Controller(App)/Service/Dao,提高可维护性。
- 持久化:文件或数据库(JDBC/ORM)。
-
常见细节与最佳实践
- 字符串比较:必须用 equals,避免使用 ==。
- Scanner 使用:连续 nextInt/nextDouble 与 nextLine 混用需注意换行处理;本案例全用 next()/nextDouble() 简化。
- 输出格式:toString 便于快速输出;也可自定义表头对齐输出。
- 安全退出:System.exit(0) 表示正常状态码,非 0 表示异常退出。
代码篇
JavaBean:商品实体类
作用/概念简述
- 封装商品数据,提供构造器、访问器和友好 toString。
通用模版
package com.itheima.pojo;
public class Goods {
private String id;
private String name;
private double price;
private String desc;
public Goods() { }
public Goods(String id, String name, double price, String desc) {
this.id = id; this.name = name; this.price = price; this.desc = desc;
}
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public double getPrice() { return price; }
public void setPrice(double price) { this.price = price; }
public String getDesc() { return desc; }
public void setDesc(String desc) { this.desc = desc; }
@Override
public String toString() {
return "Goods{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", price=" + price +
", desc='" + desc + '\'' +
'}';
}
}
属性/知识点卡片
点 | 说明 |
---|---|
封装 | 字段 private,提供 getter/setter |
构造 | 无参 + 全参 |
输出 | 重写 toString 便于调试与展示 |
主程序骨架:菜单循环与分发
作用/概念简述
- 循环输出菜单项,接收用户输入,switch 分发到对应功能。
通用模版
import com.itheima.pojo.Goods;
import java.util.ArrayList;
import java.util.Scanner;
public class App {
static ArrayList<Goods> list = new ArrayList<>();
static Scanner sc = new Scanner(System.in);
static {
list.add(new Goods("001", "华为平板", 3999, "平板电脑"));
list.add(new Goods("002", "华为手机", 6999, "手机"));
list.add(new Goods("003", "华为电脑", 8999, "电脑"));
}
public static void main(String[] args) {
while (true) {
System.out.println("-------------欢迎使用商品管理系统-------------");
System.out.println("1. 添加商品");
System.out.println("2. 删除商品");
System.out.println("3. 修改商品");
System.out.println("4. 查询全部商品");
System.out.println("5. 查询单个商品");
System.out.println("6. 退出");
System.out.println("--------------------------------------------");
System.out.print("请输入您的选择: ");
String choice = sc.next();
switch (choice) {
case "1": addGoods(); break;
case "2": deleteGoodsById(); break;
case "3": updateGoodsById(); break;
case "4": queryAllGoods(); break;
case "5": queryGoodsById(); break;
case "6":
System.out.println("感谢您的使用, 再见!");
System.exit(0);
break;
default:
System.out.println("您输入有误, 请检查后重新输入!");
}
}
}
// 各功能方法在下方
}
属性/知识点卡片
点 | 说明 |
---|---|
静态成员 | list、sc 定义为 static,便于静态方法访问 |
静态代码块 | 初始化测试数据 |
退出 | System.exit(0) 正常退出 |
工具方法:根据编号获取索引
作用/概念简述
- 在列表中查找指定 id 的商品索引,若不存在返回 -1。
通用模版
public static int getIndex(String id) {
for (int i = 0; i < list.size(); i++) {
Goods g = list.get(i);
if (g.getId().equals(id)) {
return i;
}
}
return -1;
}
属性/知识点卡片
点 | 说明 |
---|---|
比较 | 字符串必须用 equals |
复杂度 | O(n) 顺序查找 |
查询全部商品
作用/概念简述
- 遍历集合,输出所有商品信息。
通用模版
private static void queryAllGoods() {
if (list.isEmpty()) {
System.out.println("当前无商品记录。");
return;
}
System.out.println("商品信息如下:");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
属性/知识点卡片
点 | 说明 |
---|---|
判空 | 友好提示 |
输出 | 使用 toString 快速展示 |
查询单个商品
作用/概念简述
- 通过编号查找并输出该商品。
通用模版
private static void queryGoodsById() {
System.out.print("请输入要查询的商品编号:");
String id = sc.next();
int index = getIndex(id);
if (index == -1) {
System.out.println("您输入的编号不存在!");
} else {
System.out.println("查找到的商品信息为:");
System.out.println(list.get(index));
}
}
属性/知识点卡片
点 | 说明 |
---|---|
查找 | 复用 getIndex |
反馈 | 友好提示 |
添加商品(保证编号唯一)
作用/概念简述
- 录入商品信息,校验编号唯一后封装对象入集合。
通用模版
private static void addGoods() {
System.out.print("请输入商品编号: ");
String id = sc.next();
while (getIndex(id) != -1) {
System.out.print("编号已存在,请重新输入: ");
id = sc.next();
}
System.out.print("请输入商品名称: ");
String name = sc.next();
System.out.print("请输入商品价格: ");
double price = sc.nextDouble();
System.out.print("请输入商品描述: ");
String desc = sc.next();
Goods goods = new Goods(id, name, price, desc);
list.add(goods);
System.out.println("添加成功!");
}
属性/知识点卡片
点 | 说明 |
---|---|
唯一性 | while 检测,重复输入 |
封装 | 构建 Goods 再 add |
删除商品(根据编号)
作用/概念简述
- 查索引后按索引删除元素。
通用模版
private static void deleteGoodsById() {
System.out.print("请输入要删除的商品编号: ");
String id = sc.next();
int index = getIndex(id);
if (index == -1) {
System.out.println("您输入的商品号码不存在! 请检查!");
} else {
list.remove(index);
System.out.println("删除成功!");
}
}
属性/知识点卡片
点 | 说明 |
---|---|
安全删除 | 先查后删 |
提示 | 不存在给出提示 |
修改商品(根据编号)
作用/概念简述
- 查索引后用新对象替换原对象(set)。
通用模版
private static void updateGoodsById() {
System.out.print("请输入要修改的商品编号:");
String id = sc.next();
int index = getIndex(id);
if (index == -1) {
System.out.println("您输入的编号不存在!");
} else {
System.out.print("请输入要修改的商品名称:");
String name = sc.next();
System.out.print("请输入要修改的商品价格:");
double price = sc.nextDouble();
System.out.print("请输入要修改的商品描述:");
String desc = sc.next();
Goods goods = new Goods(id, name, price, desc);
list.set(index, goods);
System.out.println("修改成功!");
}
}
属性/知识点卡片
点 | 说明 |
---|---|
替换 | set(index, newGoods) |
保障 | 先查索引 |
可选增强(进阶参考)
作用/概念简述
- 提升用户体验与可维护性。
通用模版
- 统一输入工具:
private static double readDouble(String prompt) {
while (true) {
try {
System.out.print(prompt);
return Double.parseDouble(sc.next());
} catch (NumberFormatException e) {
System.out.println("输入格式有误,请重新输入数字。");
}
}
}
- 表格化输出:
private static void printTable() {
System.out.printf("%-8s %-12s %-10s %-20s%n", "编号", "名称", "价格", "描述");
for (Goods g : list) {
System.out.printf("%-8s %-12s %-10.2f %-20s%n",
g.getId(), g.getName(), g.getPrice(), g.getDesc());
}
}
- Map 存储(O(1) 查找):
// Map<String, Goods> map = new HashMap<>();
// 添加:map.put(id, goods)
// 查找:map.containsKey(id) / map.get(id)
// 删除:map.remove(id)
// 修改:map.put(id, newGoods)
属性/知识点卡片
增强点 | 说明 |
---|---|
读数健壮性 | 防止 NumberFormatException |
表格输出 | 美观对齐 |
Map | O(1) 查找、修改、删除 |