Java基础

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_HOMEC:\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            退出

属性/知识点表格

命令示例说明
cdcd C:\work\java切换目录
dirdir列表显示
mdmd src创建目录
deldel HelloWorld.class删除文件
typetype 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;类名与文件名一致
文件扩展名.javaWindows 显示扩展名需开启

片段代码案例

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类文件源码单元
SDKJDK项目/模块使用的 JDK

片段代码案例

public class Main {
    public static void main(String[] args) {
        System.out.println("Run in IDEA");
    }
}
  • 常用操作(示例快捷键,Windows 默认):
    • 新建类:Alt + Insert
    • 运行当前类:Ctrl + Shift + F10
    • 重命名:Shift + F6

常见错误与排查清单

作用/概念简述

  • 快速定位初学阶段的高频问题,保证编译运行稳定。

通用模版

  • 排查顺序:
    1. 文件名与类名一致,且 public 类名正确
    2. 已保存源码文件,扩展名为 .java(非 .txt)
    3. 命令位置在源码所在目录
    4. 运行命令不带 .class
    5. JAVA_HOME、Path 配置正确
    6. 命令行输出编码与文件编码一致(避免中文乱码)

属性/知识点表格

现象可能原因解决
‘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", truenull 不能直接打印

片段代码案例

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;

标识符命名

作用/概念简述

  • 给类、方法、变量起名的规则与规范。

通用模版

  • 规则:字母/数字/_/$,不能以数字开头,不能用关键字,区分大小写。
  • 规范:见名知义;类(大驼峰),方法/变量(小驼峰)。

属性/知识点表格

类名方法名变量名
HelloWorldgetMaxuserName

片段代码案例

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/long10, 100L首选 int;长整型加 L
小数float/double12.3F, 12.3首选 double
字符char'a', '男'底层编码 0~65535
布尔booleantrue/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 / 22
5 / 2.02.5
5 % 21

片段代码案例

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 += ba = (类型)(a + b)
a -= ba = (类型)(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 > 20false
10 <= 20true
10 == 20false
10 != 20true

片段代码案例

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 → 命令行参数数组。

代码篇


类与对象:定义、创建与使用

作用/概念简述

  • 定义类(属性+行为),通过 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
表格输出美观对齐
MapO(1) 查找、修改、删除

评论