Java 作为一门广泛应用的编程语言,凭借其跨平台性、面向对象特性和丰富的类库,在企业级开发、移动应用开发等领域占据重要地位。本文将通过大量案例代码,深入探讨 Java 的核心技术,帮助开发者更好地理解和掌握 Java 编程。
一、Java 基础语法
菜鸟教程 - Java 基础语法
Java 基础语法 | 菜鸟教程
→ 含变量/数据类型/运算符等基础内容,附带在线代码编辑器
廖雪峰的Java教程 - 程序基础
Java历史 - Java教程 - 廖雪峰的官方网站
→ 图文并茂讲解语法核心概念
1. 变量声明与数据类型
核心:
声明: 创建变量(如 int age;
, String name;
)。
数据类型: 定义变量能存储的值的种类和操作(如整数 int
, 浮点数 double
, 布尔值 boolean
, 字符 char
, 字符串 String
, 对象引用等)。
赋值: 将具体的值存储到变量中(如 age = 30;
, name = "Alice";
)。
public class VariableExample {
public static void main(String[] args) {
// 基本数据类型
byte age = 25; // 8位有符号整数
short salary = 30000; // 16位有符号整数
int population = 1400000000; // 32位有符号整数
long galaxyCount = 10000000000L; // 64位有符号整数,需加L后缀
float piFloat = 3.14159f; // 32位浮点数,需加f后缀
double piDouble = 3.1415926535; // 64位浮点数
char gender = 'M'; // 16位Unicode字符
boolean isStudent = true; // 布尔值
// 引用数据类型
String name = "Alice"; // 字符串对象
int[] numbers = {1, 2, 3, 4, 5}; // 数组
}
}
2. 字符串操作
核心操作:
连接: 将多个字符串拼接起来 (+
或 concat()
方法)。
获取长度: length()
方法。
查找/提取子串: indexOf()
, substring()
方法。
大小写转换: toLowerCase()
, toUpperCase()
方法。
替换: replace()
方法。
分割: split()
方法。
比较: equals()
(比较内容), ==
(比较对象引用,通常不用于内容比较)。
public class StringExample {
public static void main(String[] args) {
String str = "Hello, World!";
// 字符串长度
int length = str.length(); // 13
// 字符串拼接
String newStr = str + " Welcome!"; // "Hello, World! Welcome!"
// 子串截取
String subStr = str.substring(7, 12); // "World"
// 字符串替换
String replaced = str.replace("World", "Java"); // "Hello, Java!"
// 字符串分割
String[] parts = "Java,is,awesome".split(","); // ["Java", "is", "awesome"]
// 字符串比较
boolean isEqual = "Java".equals("java"); // false
boolean ignoreCase = "Java".equalsIgnoreCase("java"); // true
}
}
3. 条件语句
核心结构:
if
: 如果条件为真,则执行代码块。
else
: 如果前面的 if
条件为假,则执行此代码块(可选)。
else if
: 检查另一个条件(可选,可以有多个)。
switch
: 根据一个变量的不同值来执行不同的代码块(一种多分支选择)。
public class ConditionalExample {
public static void main(String[] args) {
int score = 85;
// if-else语句
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
// switch语句
int day = 3;
String dayName;
switch (day) {
case 1:
dayName = "周一";
break;
case 2:
dayName = "周二";
break;
case 3:
dayName = "周三";
break;
default:
dayName = "其他";
}
System.out.println(dayName); // 周三
}
}
4. 循环结构
核心类型:
for
循环: 通常用于已知循环次数的情况(如遍历数组)。包含初始化、条件检查、迭代表达式。while
循环: 在循环开始前检查条件,条件为真则执行循环体。适用于循环次数未知但条件明确的情况。
do...while
循环: 先执行一次循环体,然后检查条件。适用于至少需要执行一次且循环次数未知的情况。
循环控制: break
(跳出整个循环), continue
(跳过本次循环剩余部分,进入下一次循环)。
public class LoopExample {
public static void main(String[] args) {
// for循环:打印1到5
for (int i = 1; i <= 5; i++) {
System.out.print(i + " "); // 1 2 3 4 5
}
// while循环:计算1到100的和
int sum = 0;
int j = 1;
while (j <= 100) {
sum += j;
j++;
}
System.out.println("\nSum: " + sum); // 5050
// do-while循环:至少执行一次
int k = 0;
do {
System.out.print(k + " "); // 0
k++;
} while (k < 0);
// 增强for循环:遍历数组
int[] numbers = {10, 20, 30};
for (int num : numbers) {
System.out.print(num + " "); // 10 20 30
}
}
}
5. 方法定义与调用
核心概念:
方法签名: 方法名 + 参数列表(参数类型和顺序)。
参数: 方法执行时需要的输入数据(形参:定义时的占位符;实参:调用时传入的实际值)。
返回值: 方法执行完成后返回给调用者的结果(使用 return
语句)。
作用域: 方法内部定义的变量通常只在方法内部有效(局部变量)。
public class MethodExample {
public static void main(String[] args) {
// 调用静态方法
int sum = add(5, 3);
System.out.println("Sum: " + sum); // 8
// 创建对象调用实例方法
MethodExample obj = new MethodExample();
String reversed = obj.reverseString("Java");
System.out.println("Reversed: " + reversed); // "avaJ"
}
// 静态方法:计算两数之和
public static int add(int a, int b) {
return a + b;
}
// 实例方法:反转字符串
public String reverseString(String input) {
StringBuilder sb = new StringBuilder(input);
return sb.reverse().toString();
}
}
6. 面向对象编程基础
四大核心支柱:
封装: 将对象的数据(属性)和操作数据的方法捆绑在一起,并隐藏内部实现细节(通常通过 private
访问修饰符保护属性,提供 public
的 getter/setter
方法来访问和修改)。目的是保护数据完整性,简化使用。
抽象: 隐藏复杂的内部实现,只暴露必要的接口(方法)给外部使用。让使用者关注“做什么”而不是“怎么做”。
继承: 允许一个类(子类/派生类)继承另一个类(父类/基类/超类)的属性和方法。目的是实现代码复用和建立类之间的层次关系(is-a
关系)。子类可以扩展或覆盖父类的功能。
多态: “多种形态”。编译时多态(方法重载): 同一个类中,允许存在多个同名但参数列表不同的方法。调用哪个方法在编译时根据参数确定。
运行时多态(方法重写): 在继承关系中,子类重写(override)了父类的同名同参数的方法。当通过父类引用指向子类对象调用该方法时,实际执行的是子类重写后的方法。调用哪个方法在运行时根据对象的实际类型确定。这是OOP最强大的特性之一,提供了接口的灵活性。
// 父类:动物
class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public void eat() {
System.out.println(name + " is eating.");
}
public String getName() {
return name;
}
}
// 子类:狗,继承自Animal
class Dog extends Animal {
public Dog(String name) {
super(name);
}
// 重写父类方法
@Override
public void eat() {
System.out.println(getName() + " is eating bones.");
}
// 子类特有方法
public void bark() {
System.out.println(getName() + " is barking.");
}
}
public class OOPExample {
public static void main(String[] args) {
Animal animal = new Animal("Generic Animal");
animal.eat(); // Generic Animal is eating.
Dog dog = new Dog("Buddy");
dog.eat(); // Buddy is eating bones.
dog.bark(); // Buddy is barking.
// 多态:父类引用指向子类对象
Animal animalDog = new Dog("Max");
animalDog.eat(); // Max is eating bones.
// animalDog.bark(); // 编译错误:父类引用无法调用子类特有方法
}
}
7. 数组操作
核心操作:
创建: int[] numbers = new int[5];
(指定长度), String[] names = {"Alice", "Bob", "Charlie"};
(初始化元素)。
访问元素: 通过索引(下标,从0开始)访问,如 names[0]
获取第一个元素。
修改元素: 通过索引赋值,如 numbers[2] = 100;
。
获取长度: array.length
属性(注意不是方法)。
遍历: 通常使用 for
循环或 foreach
(增强for循环) 访问数组每个元素。
多维数组: 数组的数组(如 int[][] matrix = new int[3][4];
)。
常见操作: 查找元素、排序、复制等(这些功能常由工具类如 Arrays
提供)。
public class ArrayExample {
public static void main(String[] args) {
// 一维数组
int[] numbers = new int[5];
for (int i = 0; i < numbers.length; i++) {
numbers[i] = i * 2;
}
// 二维数组
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 遍历二维数组
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
// 数组拷贝
int[] copy = Arrays.copyOf(numbers, numbers.length);
System.out.println(Arrays.toString(copy)); // [0, 2, 4, 6, 8]
// 数组排序
int[] unsorted = {5, 3, 8, 1};
Arrays.sort(unsorted);
System.out.println(Arrays.toString(unsorted)); // [1, 3, 5, 8]
}
}
8. 异常处理
核心概念:
异常: 程序执行过程中发生的事件,它中断了正常的指令流。通常代表错误(如文件找不到、除零、空指针访问、网络中断等)。
异常类型: 通常有层次结构(如 Exception
, RuntimeException
, IOException
等)。
try-catch
块:
try
: 包裹可能抛出异常的代码。
catch
: 捕获并处理特定类型的异常。可以有多个 catch
块处理不同类型的异常。
finally
块:
无 论是否发生异常,finally
块中的代码都会执行。常用于释放资源(如关闭文件、数据库连接)。
throw
: 在代码中主动抛出一个异常。throws
: 在方法声明上声明该方法可能抛出的异常类型(通知调用者需要处理这些异常)。
public class ExceptionExample {
public static void main(String[] args) {
try {
// 可能抛出异常的代码
int result = divide(10, 0);
System.out.println("Result: " + result);
} catch (ArithmeticException e) {
// 捕获算术异常
System.out.println("Error: " + e.getMessage()); // 除数不能为零
} catch (Exception e) {
// 捕获其他异常
e.printStackTrace();
} finally {
// 无论是否发生异常都会执行
System.out.println("Finally block executed.");
}
}
public static int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("除数不能为零");
}
return a / b;
}
}
9. 枚举类型
特点:
声明的枚举值是该枚举类型的唯一实例。
类型安全,避免使用整数或字符串常量带来的歧义和错误。
可以有自己的属性和方法。
常用于表示状态(如 ON
, OFF
)、模式(如 MODE_A
, MODE_B
)、类别(如 MONDAY
, TUESDAY
, ..., SUNDAY
)、选项等。
public class EnumExample {
// 定义枚举类型
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public static void main(String[] args) {
Day today = Day.MONDAY;
// 枚举遍历
for (Day day : Day.values()) {
System.out.println(day);
}
// 枚举 switch
switch (today) {
case MONDAY:
System.out.println("今天是周一");
break;
case FRIDAY:
System.out.println("今天是周五");
break;
default:
System.out.println("今天是工作日");
}
}
}
10. 输入输出处理
核心:
标准输入/输出:
通常是控制台(命令行)。
输出:System.out.println()
/ System.out.print()
(向控制台打印信息)。
输入:Scanner
类 (Java) 或 System.console().readLine()
等(从控制台读取用户输入)。
文件输入/输出:
核心类:File
, FileInputStream
/FileOutputStream
(字节流), FileReader
/FileWriter
(字符流), BufferedReader
/BufferedWriter
(缓冲提高效率)。
步骤:打开文件 -> 读/写数据 -> 关闭文件(非常重要!通常在 finally
块或 try-with-resources
语句中关闭)
import java.util.Scanner;
public class InputOutputExample {
public static void main(String[] args) {
// 控制台输入
Scanner scanner = new Scanner(System.in);
System.out.print("请输入你的姓名: ");
String name = scanner.nextLine();
System.out.print("请输入你的年龄: ");
int age = scanner.nextInt();
// 格式化输出
System.out.printf("你好,%s!你今年%d岁了。%n", name, age);
// 文件输出示例(需处理异常)
try (java.io.PrintWriter writer = new java.io.PrintWriter("output.txt")) {
writer.println("这是写入文件的内容");
writer.printf("姓名: %s, 年龄: %d%n", name, age);
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
}
二、面向对象编程
Java官方教程中文版(对象概念)
https://docs.oracle.com/javase/tutorial/java/concepts/index.html
→ 官方权威解读(右上角可切换中文)
慕课网 - Java面向对象精讲
用iptables搭建一套强大的安全防护盾-慕课网
→ 免费视频课程(需注册)
2.1类与对象基础
概念
- 类:是对象的抽象模板,定义属性(成员变量)和行为(方法)。
- 对象:是类的实例,通过
new
创建,拥有类定义的属性和方法。 - 封装:通过访问控制(
private
、public
)隐藏内部实现,仅暴露必要接口。
案例
class Shape {
protected String color; // 封装属性
public Shape(String color) { // 构造方法
this.color = color;
}
public String getColor() { // 访问器方法
return color;
}
public double getArea() { // 虚方法(子类可重写)
return 0;
}
}
class Circle extends Shape {
private double radius;
public Circle(String color, double radius) {
super(color); // 调用父类构造
this.radius = radius;
}
@Override
public double getArea() { // 重写父类方法
return Math.PI * radius * radius;
}
}
2.2继承与多态
概念
- 继承:子类通过
extends
继承父类的属性和方法,实现代码复用。 - 多态:父类引用指向子类对象,通过方法重写实现运行时行为差异。
- 抽象类:含抽象方法的类,不能实例化,强制子类实现抽象方法。
案例
abstract class Animal { // 抽象类
public abstract void makeSound(); // 抽象方法
}
class Dog extends Animal {
@Override
public void makeSound() { // 实现抽象方法
System.out.println("汪汪");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("喵喵");
}
}
// 多态调用
Animal dog = new Dog();
dog.makeSound(); // 输出:汪汪
2.3接口实现
概念
- 接口:纯抽象类型,定义方法签名但不实现,支持多继承。
- 实现:类通过
implements
实现接口,必须实现所有方法。 - 默认方法(Java 8+):接口中可定义默认实现的方法。
案例
interface Flyable {
void fly(); // 抽象方法
}
interface Swimable {
default void swim() { // 默认方法
System.out.println("游泳");
}
}
class Duck implements Flyable, Swimable {
@Override
public void fly() { // 实现接口方法
System.out.println("飞翔");
}
}
2.4封装与访问控制
概念
- 封装:将数据(属性)和操作(方法)绑定,通过访问修饰符控制可见性。
- 访问修饰符:
private
:仅类内部可见。protected
:类及其子类、同一包内可见。public
:全局可见。- 默认:同一包内可见。
案例
class BankAccount {
private double balance; // 私有属性,外部不可直接访问
public void deposit(double amount) { // 公共方法
if (amount > 0) {
balance += amount;
}
}
public double getBalance() { // 访问器方法
return balance;
}
}
2.5静态成员与单例模式
概念
- 静态成员:用
static
修饰的属性或方法,属于类而非实例。 - 单例模式:确保类仅有一个实例,并提供全局访问点。
案例
class Counter {
private static int count = 0; // 静态变量,所有实例共享
public static int getCount() { // 静态方法
return count;
}
}
class Singleton {
private static final Singleton INSTANCE = new Singleton(); // 饿汉式单例
private Singleton() {} // 私有构造方法
public static Singleton getInstance() {
return INSTANCE;
}
}
2.6内部类与匿名类
概念
- 成员内部类:定义在类内部,可访问外部类私有成员。
- 静态内部类:用
static
修饰的内部类,不依赖外部类实例。 - 匿名类:临时实现接口或继承类的一次性类。
案例
class Outer {
private int x = 10;
class Inner { // 成员内部类
public void printX() {
System.out.println(x); // 直接访问外部类私有成员
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner(); // 创建内部类实例
inner.printX(); // 输出:10
// 匿名类示例
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("匿名类执行");
}
};
}
}
2.7方法重载与重写
概念
- 重载 (Overload):同一类中方法名相同但参数列表不同。
- 重写 (Override):子类修改父类的方法实现(方法签名必须相同)。
案例
class Calculator {
public int add(int a, int b) { // 方法重载
return a + b;
}
public double add(double a, double b) { // 参数类型不同
return a + b;
}
}
class AdvancedCalculator extends Calculator {
@Override
public double add(double a, double b) { // 方法重写
return Math.round(a + b); // 修改实现逻辑
}
}
2.8抽象类与模板方法模式
概念
- 抽象类:含抽象方法的类,不能实例化,为子类提供统一接口。
- 模板方法:定义算法骨架,将具体步骤延迟到子类实现。
案例
abstract class Game {
public final void play() { // 模板方法
initialize();
start();
end();
}
protected abstract void initialize(); // 抽象方法,子类实现
protected abstract void start();
protected abstract void end();
}
class Football extends Game {
@Override
protected void initialize() {
System.out.println("初始化足球场");
}
@Override
protected void start() {
System.out.println("开球");
}
@Override
protected void end() {
System.out.println("裁判吹哨结束");
}
}
总结对比
概念 | 核心作用 | 关键语法 | 典型场景 |
---|---|---|---|
类与对象 | 封装数据与行为 | 构造方法、成员变量 / 方法 | 数据模型(用户、订单) |
继承与多态 | 代码复用、运行时行为差异化 | extends 、abstract 、@Override | 插件系统、策略模式 |
接口实现 | 定义契约,支持多继承 | implements 、默认方法 | 事件监听、服务提供者 |
封装与访问控制 | 隐藏实现细节,保护数据 | private 、public 、protected | 安全敏感数据(账户余额) |
静态成员 | 类级别的属性和方法 | static | 工具类(Math)、计数器 |
内部类 | 逻辑分组,访问外部类私有成员 | 成员内部类、静态内部类 | GUI 事件处理、数据结构嵌套 |
方法重载 / 重写 | 增强方法灵活性与扩展性 | 方法签名、@Override 注解 | 输入参数多样化、子类定制化 |
抽象类与模板方法 | 定义算法骨架,强制子类实现特定步骤 | abstract 类、final 方法 | 工作流引擎、游戏初始化流程 |
三、Java 集合框架
Java Collections Framework 官方文档
https://docs.oracle.com/javase/8/docs/technotes/guides/collections/overview.html
→ 架构设计原理解析
优快云技术社区 - 集合框架全景图
https://blog.youkuaiyun.com/u013256816/article/details/51098811
→ 包含类关系图和使用场景分析
3.1 List 集合
List
是一个有序、可重复的集合,常用的实现类有ArrayList
和LinkedList
。
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
// 使用增强for循环遍历
for (String fruit : fruits) {
System.out.println(fruit);
}
// 使用迭代器遍历
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 使用索引遍历
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
}
}
3.2 Map 集合
Map
用于存储键值对,常用的实现类有HashMap
和TreeMap
。
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 88);
scores.put("Charlie", 92);
// 遍历键值对
for (Map.Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// 仅遍历键
for (String key : scores.keySet()) {
System.out.println("Key: " + key);
}
// 仅遍历值
for (Integer value : scores.values()) {
System.out.println("Value: " + value);
}
}
}
3.3 Set 集合
Set
是一个不允许重复元素的集合,常用的实现类有HashSet
和TreeSet
。
import java.util.HashSet;
import java.util.Set;
public class SetExample {
public static void main(String[] args) {
Set<String> names = new HashSet<>();
names.add("Alice");
names.add("Bob");
names.add("Charlie");
names.add("Alice"); // 重复元素,不会被添加
System.out.println("Set size: " + names.size()); // 输出3
// 遍历Set
for (String name : names) {
System.out.println(name);
}
// 检查元素是否存在
boolean containsBob = names.contains("Bob");
System.out.println("Contains Bob: " + containsBob); // 输出true
// 删除元素
names.remove("Charlie");
System.out.println("Set after removing Charlie: " + names);
}
}
3.4 Queue 集合
Queue
是一个队列接口,遵循 FIFO(先进先出)原则,常用的实现类有LinkedList
和PriorityQueue
。
import java.util.LinkedList;
import java.util.Queue;
public class QueueExample {
public static void main(String[] args) {
Queue<String> queue = new LinkedList<>();
// 入队操作
queue.offer("Element 1");
queue.offer("Element 2");
queue.offer("Element 3");
System.out.println("Queue: " + queue); // 输出: [Element 1, Element 2, Element 3]
// 出队操作
String firstElement = queue.poll();
System.out.println("Polled element: " + firstElement); // 输出: Element 1
System.out.println("Queue after poll: " + queue); // 输出: [Element 2, Element 3]
// 查看队首元素但不出队
String peekElement = queue.peek();
System.out.println("Peeked element: " + peekElement); // 输出: Element 2
// 检查队列是否为空
boolean isEmpty = queue.isEmpty();
System.out.println("Is queue empty? " + isEmpty); // 输出: false
// 遍历队列
System.out.println("Queue elements:");
for (String element : queue) {
System.out.println(element);
}
}
}
3.5 List 集合进阶操作
以下示例展示了ArrayList
的排序、截取和转换操作:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListAdvancedExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(5);
numbers.add(2);
numbers.add(8);
numbers.add(1);
System.out.println("Original list: " + numbers); // 输出: [5, 2, 8, 1]
// 升序排序
Collections.sort(numbers);
System.out.println("Sorted list: " + numbers); // 输出: [1, 2, 5, 8]
// 降序排序
Collections.sort(numbers, Collections.reverseOrder());
System.out.println("Reverse sorted list: " + numbers); // 输出: [8, 5, 2, 1]
// 截取子列表
List<Integer> subList = numbers.subList(1, 3); // 索引1(包含)到3(不包含)
System.out.println("Sub list: " + subList); // 输出: [5, 2]
// 将List转换为数组
Integer[] array = numbers.toArray(new Integer[0]);
System.out.print("Array: ");
for (Integer num : array) {
System.out.print(num + " "); // 输出: 8 5 2 1
}
}
}
3.6 Map 集合进阶操作
以下示例展示了HashMap
的统计和过滤操作:
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class MapAdvancedExample {
public static void main(String[] args) {
Map<String, Integer> scores = new HashMap<>();
scores.put("Alice", 95);
scores.put("Bob", 88);
scores.put("Charlie", 92);
scores.put("David", 78);
System.out.println("Original scores: " + scores);
// 过滤分数大于90的学生
Map<String, Integer> highScores = scores.entrySet().stream()
.filter(entry -> entry.getValue() > 90)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
System.out.println("High scores: " + highScores); // 输出: {Alice=95, Charlie=92}
// 计算总分
int totalScore = scores.values().stream().mapToInt(Integer::intValue).sum();
System.out.println("Total score: " + totalScore); // 输出: 353
// 查找最高分
int maxScore = scores.values().stream().mapToInt(Integer::intValue).max().orElse(0);
System.out.println("Max score: " + maxScore); // 输出: 95
// 查找最低分
int minScore = scores.values().stream().mapToInt(Integer::intValue).min().orElse(0);
System.out.println("Min score: " + minScore); // 输出: 78
}
}
四、Java项目中实际应用集合框架的案例
GitHub热门项目 - Java电商系统
https://github.com/macrozheng/mall
→ 查看service
模块中的购物车/订单服务(使用ArrayList/HashMap/ConcurrentHashMap)
博客园 - 集合框架在ERP系统中的应用
https://www.cnblogs.com/jingmoxukong/p/14404304.html
→ 员工管理/库存系统等场景代码示例
4.1用户管理系统 - 使用 Map 存储用户信息
在 Web 应用中,常使用HashMap
存储用户会话信息,实现快速登录验证:
import java.util.HashMap;
import java.util.Map;
public class UserManager {
private Map<String, User> userDatabase = new HashMap<>();
// 注册新用户
public void registerUser(String username, String password) {
userDatabase.put(username, new User(username, password));
}
// 用户登录验证
public boolean authenticate(String username, String password) {
User user = userDatabase.get(username);
return user != null && user.getPassword().equals(password);
}
// 获取在线用户数
public int getActiveUserCount() {
return userDatabase.size();
}
// 内部用户类
private static class User {
private final String username;
private final String password;
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
}
}
4.2电商系统 - 使用 List 和 Map 处理订单数据
订单系统中,使用List
存储订单列表,Map
按用户 ID 分组订单:
import java.util.*;
public class OrderService {
private List<Order> allOrders = new ArrayList<>();
// 创建新订单
public void createOrder(String userId, double amount) {
Order newOrder = new Order(UUID.randomUUID().toString(), userId, amount);
allOrders.add(newOrder);
}
// 按用户ID查询订单
public List<Order> getOrdersByUser(String userId) {
return allOrders.stream()
.filter(order -> order.getUserId().equals(userId))
.toList();
}
// 统计每个用户的订单总数
public Map<String, Integer> countOrdersByUser() {
Map<String, Integer> result = new HashMap<>();
for (Order order : allOrders) {
result.put(order.getUserId(), result.getOrDefault(order.getUserId(), 0) + 1);
}
return result;
}
private static class Order {
private final String orderId;
private final String userId;
private final double amount;
public Order(String orderId, String userId, double amount) {
this.orderId = orderId;
this.userId = userId;
this.amount = amount;
}
public String getUserId() {
return userId;
}
}
}
4.3缓存系统 - 使用 LinkedHashMap 实现 LRU 缓存
利用LinkedHashMap
的访问顺序特性,实现最近最少使用 (LRU) 缓存:
import java.util.LinkedHashMap;
import java.util.Map;
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
// 初始容量、负载因子、accessOrder设为true表示按访问顺序排序
super(capacity, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity; // 超过容量时自动移除最旧元素
}
};
this.capacity = capacity;
}
public static void main(String[] args) {
LRUCache<String, String> cache = new LRUCache<>(3);
cache.put("key1", "value1");
cache.put("key2", "value2");
cache.put("key3", "value3");
cache.get("key1"); // 访问key1,使其变为最近使用
cache.put("key4", "value4"); // 添加新元素,触发LRU淘汰
System.out.println(cache); // 输出: {key3=value3, key1=value1, key4=value4}
}
}
4.4数据统计 - 使用 Set 去重和频率统计
处理日志数据时,使用HashSet
去重并统计 IP 访问次数:
import java.util.*;
public class LogAnalyzer {
private final List<String> accessLogs;
public LogAnalyzer(List<String> accessLogs) {
this.accessLogs = accessLogs;
}
// 统计唯一IP数量
public int countUniqueIPs() {
Set<String> uniqueIPs = new HashSet<>();
for (String log : accessLogs) {
String ip = extractIPFromLog(log);
uniqueIPs.add(ip);
}
return uniqueIPs.size();
}
// 统计每个IP的访问频率
public Map<String, Integer> countIPFrequency() {
Map<String, Integer> frequencyMap = new HashMap<>();
for (String log : accessLogs) {
String ip = extractIPFromLog(log);
frequencyMap.put(ip, frequencyMap.getOrDefault(ip, 0) + 1);
}
return frequencyMap;
}
private String extractIPFromLog(String log) {
// 实际项目中可能使用正则表达式解析IP
return log.split(" ")[0];
}
}
4.5任务调度 - 使用 PriorityQueue 实现任务队列
基于优先级的任务调度系统,使用PriorityQueue
管理待执行任务:
import java.util.PriorityQueue;
import java.util.Queue;
public class TaskScheduler {
private final Queue<Task> taskQueue = new PriorityQueue<>();
// 添加任务到队列
public void addTask(Task task) {
taskQueue.offer(task);
}
// 执行最高优先级任务
public Task executeNextTask() {
return taskQueue.poll();
}
// 查看队列中的任务数
public int getPendingTaskCount() {
return taskQueue.size();
}
public static class Task implements Comparable<Task> {
private final String name;
private final int priority; // 值越小优先级越高
public Task(String name, int priority) {
this.name = name;
this.priority = priority;
}
@Override
public int compareTo(Task other) {
return Integer.compare(this.priority, other.priority);
}
@Override
public String toString() {
return "Task{name='" + name + "', priority=" + priority + "}";
}
}
}
4.6社交网络 - 使用 Map 和 List 构建好友关系
社交平台中,使用Map
存储用户及其好友列表:
import java.util.*;
public class SocialNetwork {
private final Map<String, List<String>> userConnections = new HashMap<>();
// 添加用户
public void addUser(String username) {
userConnections.putIfAbsent(username, new ArrayList<>());
}
// 添加好友关系
public void addFriend(String userA, String userB) {
userConnections.computeIfAbsent(userA, k -> new ArrayList<>()).add(userB);
userConnections.computeIfAbsent(userB, k -> new ArrayList<>()).add(userA);
}
// 获取用户的所有好友
public List<String> getFriends(String username) {
return userConnections.getOrDefault(username, Collections.emptyList());
}
// 查找共同好友
public Set<String> findCommonFriends(String userA, String userB) {
List<String> friendsA = getFriends(userA);
List<String> friendsB = getFriends(userB);
Set<String> commonFriends = new HashSet<>(friendsA);
commonFriends.retainAll(friendsB);
return commonFriends;
}
}
4.7数据处理 - 使用 TreeSet 实现自动排序
排行榜系统中,使用TreeSet
自动维护数据的排序:
import java.util.Set;
import java.util.TreeSet;
public class Leaderboard {
private final Set<Player> players = new TreeSet<>();
// 添加玩家分数
public void addScore(String playerName, int score) {
players.remove(new Player(playerName, 0)); // 移除旧记录
players.add(new Player(playerName, score)); // 添加新记录
}
// 获取排名前三的玩家
public void printTopThree() {
int rank = 1;
for (Player player : players) {
if (rank > 3) break;
System.out.printf("%d. %s - %d points%n", rank++, player.name, player.score);
}
}
private static class Player implements Comparable<Player> {
private final String name;
private final int score;
public Player(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public int compareTo(Player other) {
// 分数降序,分数相同则按名称升序
int scoreCompare = Integer.compare(other.score, this.score);
return scoreCompare != 0 ? scoreCompare : this.name.compareTo(other.name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Player player = (Player) o;
return name.equals(player.name);
}
@Override
public int hashCode() {
return name.hashCode();
}
}
}
4.8消息队列 - 使用 BlockingQueue 实现生产者 - 消费者模式
多线程环境下,使用BlockingQueue
实现线程安全的消息队列:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class MessageQueueExample {
private static final BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
public static void main(String[] args) {
// 生产者线程
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
String message = "Message-" + i;
queue.put(message);
System.out.println("Produced: " + message);
Thread.sleep(500);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
// 消费者线程
Thread consumer = new Thread(() -> {
try {
while (true) {
String message = queue.take();
System.out.println("Consumed: " + message);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
4.9图算法 - 使用邻接表表示图结构
在图算法中,使用Map
和List
构建邻接表表示图:
import java.util.*;
public class Graph {
private final Map<Integer, List<Integer>> adjacencyList = new HashMap<>();
// 添加顶点
public void addVertex(int vertex) {
adjacencyList.putIfAbsent(vertex, new ArrayList<>());
}
// 添加边
public void addEdge(int src, int dest) {
adjacencyList.computeIfAbsent(src, k -> new ArrayList<>()).add(dest);
adjacencyList.computeIfAbsent(dest, k -> new ArrayList<>()).add(src); // 无向图
}
// 广度优先搜索
public void bfs(int start) {
Set<Integer> visited = new HashSet<>();
Queue<Integer> queue = new LinkedList<>();
visited.add(start);
queue.offer(start);
while (!queue.isEmpty()) {
int current = queue.poll();
System.out.print(current + " ");
for (int neighbor : adjacencyList.getOrDefault(current, Collections.emptyList())) {
if (!visited.contains(neighbor)) {
visited.add(neighbor);
queue.offer(neighbor);
}
}
}
}
}
4.10配置管理 - 使用 Properties 加载配置文件
应用程序中,使用Properties
加载配置文件并解析:
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
public class ConfigManager {
private final Properties properties = new Properties();
public ConfigManager(String configFilePath) throws IOException {
try (FileInputStream fis = new FileInputStream(configFilePath)) {
properties.load(fis);
}
}
// 获取数据库连接信息
public String getDatabaseUrl() {
return properties.getProperty("db.url");
}
// 获取缓存大小配置
public int getCacheSize() {
return Integer.parseInt(properties.getProperty("cache.size", "100"));
}
// 获取所有配置项
public Properties getAllProperties() {
return (Properties) properties.clone();
}
}
推荐辅助工具:
Java可视化调试工具:
Java Visualizer
→ 实时观察对象内存状态
五、实战
图书借阅管理系统
这是一个基于SpringBoot + Vue.js的图书借阅管理系统,适合Java初学者学习。
## 项目结构
```
图书借阅管理系统/
├── backend/ # 后端SpringBoot项目
│ ├── src/
│ ├── pom.xml
│ └── README.md
├── frontend/ # 前端Vue.js项目
│ ├── src/
│ ├── package.json
│ └── README.md
└── README.md # 项目总说明
```
## 功能特性
- 📚 图书信息管理(增删改查)
- 🔄 借阅/归还流程
- 📋 借阅记录查询
- ⏰ 逾期提醒(模拟)
- 👤 用户管理
- 📊 数据统计
## 技术栈
# 图书借阅管理系统 - 后端
基于SpringBoot的图书借阅管理系统后端API。
## 技术栈
- Spring Boot 2.7.0
- Spring Data JPA
- MySQL 8.0
- Maven
- Lombok
## 项目结构
```
src/main/java/com/library/
├── LibraryManagementApplication.java # 主启动类
├── config/
│ └── DataInitializer.java # 数据初始化器
├── controller/
│ ├── BookController.java # 图书控制器
│ ├── BorrowController.java # 借阅控制器
│ └── UserController.java # 用户控制器
├── entity/
│ ├── Book.java # 图书实体
│ ├── User.java # 用户实体
│ └── BorrowRecord.java # 借阅记录实体
├── repository/
│ ├── BookRepository.java # 图书数据访问层
│ ├── UserRepository.java # 用户数据访问层
│ └── BorrowRecordRepository.java # 借阅记录数据访问层
└── service/
├── BookService.java # 图书服务层
├── UserService.java # 用户服务层
└── BorrowService.java # 借阅服务层
```
## 快速开始
### 1. 环境要求
- JDK 8+
- Maven 3.6+
- MySQL 8.0+
### 2. 数据库配置
1. 创建MySQL数据库:
```sql
CREATE DATABASE library_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
```
2. 修改 `application.yml` 中的数据库连接信息:
```yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/library_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: your_username
password: your_password
```
### 3. 运行项目
```bash
# 进入backend目录
cd backend
# 编译项目
mvn clean compile
# 运行项目
mvn spring-boot:run
```
项目启动后,访问地址:http://localhost:8080
## API接口
### 用户管理
- `GET /api/users` - 获取所有用户
- `GET /api/users/{id}` - 根据ID获取用户
- `POST /api/users/login` - 用户登录
- `POST /api/users/register` - 用户注册
- `PUT /api/users/{id}` - 更新用户信息
- `DELETE /api/users/{id}` - 删除用户
### 图书管理
- `GET /api/books` - 获取所有图书
- `GET /api/books/{id}` - 根据ID获取图书
- `POST /api/books` - 添加图书
- `PUT /api/books/{id}` - 更新图书
- `DELETE /api/books/{id}` - 删除图书
- `GET /api/books/search` - 搜索图书
- `GET /api/books/available` - 获取可借阅图书
### 借阅管理
- `POST /api/borrows/borrow` - 借阅图书
- `POST /api/borrows/return/{recordId}` - 归还图书
- `GET /api/borrows/user/{userId}` - 获取用户借阅记录
- `GET /api/borrows/overdue` - 获取逾期记录
- `GET /api/borrows` - 获取所有借阅记录
## 测试数据
项目启动时会自动初始化以下测试数据:
### 用户账号
- 管理员:admin / admin123
- 普通用户:user1 / user123
- 普通用户:user2 / user123
### 图书数据
- Java编程思想
- Spring实战
- Vue.js实战
- 算法导论
- 设计模式
# 图书借阅管理系统 - 前端
基于Vue.js 3 + Element Plus的图书借阅管理系统前端界面。
## 技术栈
- Vue.js 3
- Vue Router 4
- Element Plus
- Axios
- Vite
## 项目结构
```
src/
├── api/
│ └── index.js # API接口封装
├── router/
│ └── index.js # 路由配置
├── views/
│ ├── Login.vue # 登录页面
│ ├── Dashboard.vue # 仪表盘
│ ├── BookList.vue # 图书列表
│ ├── BookForm.vue # 图书表单
│ ├── BorrowList.vue # 借阅列表
│ ├── UserList.vue # 用户列表
│ └── OverdueList.vue # 逾期列表
├── App.vue # 根组件
├── main.js # 入口文件
└── style.css # 全局样式
```
## 快速开始
### 1. 环境要求
- Node.js 16+
- npm 或 yarn
### 2. 安装依赖
```bash
# 进入frontend目录
cd frontend
# 安装依赖
npm install
```
### 3. 运行项目
```bash
# 开发模式
npm run dev
```
项目启动后,访问地址:http://localhost:3000
### 4. 构建项目
```bash
# 构建生产版本
npm run build
# 预览构建结果
npm run preview
```
## 功能特性
### 用户管理
- 用户登录/退出
- 用户权限控制
- 个人信息管理
### 图书管理
- 图书列表展示
- 图书搜索功能
- 图书增删改查
- 图书分类管理
### 借阅管理
- 图书借阅
- 图书归还
- 借阅记录查询
- 借阅状态管理
### 逾期提醒
- 逾期记录查看
- 逾期提醒功能
- 逾期统计分析
### 数据统计
- 图书统计
- 借阅统计
- 用户统计
- 逾期统计
## 页面说明
### 登录页面
- 用户登录界面
- 支持管理员和普通用户登录
- 测试账号提供
### 仪表盘
- 系统概览
- 统计数据展示
- 最近借阅记录
- 逾期提醒
### 图书管理
- 图书列表页面
- 图书搜索和筛选
- 图书添加/编辑表单
- 图书删除功能
### 借阅管理
- 借阅记录列表
- 借阅/归还操作
- 借阅状态管理
- 借阅历史查询
### 用户管理(管理员)
- 用户列表管理
- 用户信息编辑
- 用户权限管理
- 用户状态控制
### 逾期提醒
- 逾期记录查看
- 逾期提醒功能
- 逾期统计分析
## 快速开始
### 后端启动
1. 进入backend目录
2. 配置数据库连接
3. 运行 `mvn spring-boot:run`
### 前端启动
1. 进入frontend目录
2. 运行 `npm install`
3. 运行 `npm run dev`
管理员登录:
实现类:
LibraryManagementApplication
package com.library;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 图书借阅管理系统主启动类
*
* @author 图书管理系统
*/
@SpringBootApplication
public class LibraryManagementApplication {
public static void main(String[] args) {
SpringApplication.run(LibraryManagementApplication.class, args);
System.out.println("图书借阅管理系统启动成功!");
System.out.println("访问地址: http://localhost:8080");
}
}
book:
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import javax.persistence.*;
import java.util.Date;
/**
* 图书实体类使用 JPA 注解将 Java 对象映射到数据库表
*/
@Entity
@Table(name = "books")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 100)
private String title; // 书名
@Column(length = 100)
private String author; // 作者
@Column(length = 50)
private String isbn; // ISBN号
@Column(length = 100)
private String publisher; // 出版社
@Column(length = 500)
private String description; // 图书描述
@Column(nullable = false)
private Integer totalCopies; // 总册数
@Column(nullable = false)
private Integer availableCopies; // 可借册数
@Column(length = 50)
private String category; // 分类
@Column(length = 20)
private String status; // 状态:AVAILABLE, UNAVAILABLE
@Column(name = "created_time", updatable = false)
private Date createdTime;
@Column(name = "updated_time")
private Date updatedTime;
@PrePersist
protected void onCreate() {
createdTime = new Date();
updatedTime = new Date();
}
@PreUpdate
protected void onUpdate() {
updatedTime = new Date();
}
}
BookRepository
import com.library.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
/**
* 图书数据访问层
*/
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
/**
* 根据书名模糊查询
*/
List<Book> findByTitleContainingIgnoreCase(String title);
/**
* 根据作者模糊查询
*/
List<Book> findByAuthorContainingIgnoreCase(String author);
/**
* 根据ISBN查询
*/
Optional<Book> findByIsbn(String isbn);
/**
* 根据分类查询
*/
List<Book> findByCategory(String category);
/**
* 根据状态查询
*/
List<Book> findByStatus(String status);
/**
* 查询可借阅的图书
*/
List<Book> findByAvailableCopiesGreaterThan(Integer copies);
/**
* 综合查询
*/
@Query("SELECT b FROM Book b WHERE " +
"(:title IS NULL OR b.title LIKE %:title%) AND " +
"(:author IS NULL OR b.author LIKE %:author%) AND " +
"(:category IS NULL OR b.category = :category) AND " +
"(:status IS NULL OR b.status = :status)")
List<Book> findByConditions(@Param("title") String title,
@Param("author") String author,
@Param("category") String category,
@Param("status") String status);
}
BookService
import com.library.entity.Book;
import com.library.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
/**
* 图书服务层
*/
@Service
@Transactional
public class BookService {
@Autowired
private BookRepository bookRepository;
/**
* 获取所有图书
*/
public List<Book> getAllBooks() {
return bookRepository.findAll();
}
/**
* 根据ID获取图书
*/
public Optional<Book> getBookById(Long id) {
return bookRepository.findById(id);
}
/**
* 添加图书
*/
public Book addBook(Book book) {
// 设置默认状态
if (book.getStatus() == null) {
book.setStatus("AVAILABLE");
}
return bookRepository.save(book);
}
/**
* 更新图书信息
*/
public Book updateBook(Long id, Book bookDetails) {
Optional<Book> optionalBook = bookRepository.findById(id);
if (optionalBook.isPresent()) {
Book book = optionalBook.get();
book.setTitle(bookDetails.getTitle());
book.setAuthor(bookDetails.getAuthor());
book.setIsbn(bookDetails.getIsbn());
book.setPublisher(bookDetails.getPublisher());
book.setDescription(bookDetails.getDescription());
book.setTotalCopies(bookDetails.getTotalCopies());
book.setAvailableCopies(bookDetails.getAvailableCopies());
book.setCategory(bookDetails.getCategory());
book.setStatus(bookDetails.getStatus());
return bookRepository.save(book);
}
return null;
}
/**
* 删除图书
*/
public boolean deleteBook(Long id) {
if (bookRepository.existsById(id)) {
bookRepository.deleteById(id);
return true;
}
return false;
}
/**
* 根据书名搜索图书
*/
public List<Book> searchBooksByTitle(String title) {
return bookRepository.findByTitleContainingIgnoreCase(title);
}
/**
* 根据作者搜索图书
*/
public List<Book> searchBooksByAuthor(String author) {
return bookRepository.findByAuthorContainingIgnoreCase(author);
}
/**
* 根据分类查询图书
*/
public List<Book> getBooksByCategory(String category) {
return bookRepository.findByCategory(category);
}
/**
* 获取可借阅的图书
*/
public List<Book> getAvailableBooks() {
return bookRepository.findByAvailableCopiesGreaterThan(0);
}
/**
* 综合查询图书
*/
public List<Book> searchBooks(String title, String author, String category, String status) {
return bookRepository.findByConditions(title, author, category, status);
}
/**
* 借阅图书(减少可借数量)
*/
public boolean borrowBook(Long bookId) {
Optional<Book> optionalBook = bookRepository.findById(bookId);
if (optionalBook.isPresent()) {
Book book = optionalBook.get();
if (book.getAvailableCopies() > 0) {
book.setAvailableCopies(book.getAvailableCopies() - 1);
bookRepository.save(book);
return true;
}
}
return false;
}
/**
* 归还图书(增加可借数量)
*/
public boolean returnBook(Long bookId) {
Optional<Book> optionalBook = bookRepository.findById(bookId);
if (optionalBook.isPresent()) {
Book book = optionalBook.get();
if (book.getAvailableCopies() < book.getTotalCopies()) {
book.setAvailableCopies(book.getAvailableCopies() + 1);
bookRepository.save(book);
return true;
}
}
return false;
}
}
BookController
import com.library.entity.Book;
import com.library.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 图书控制器
*/
@RestController
@RequestMapping("/api/books")
@CrossOrigin(origins = "*")
public class BookController {
@Autowired
private BookService bookService;
/**
* 获取所有图书
*/
@GetMapping
public ResponseEntity<List<Book>> getAllBooks() {
List<Book> books = bookService.getAllBooks();
return ResponseEntity.ok(books);
}
/**
* 根据ID获取图书
*/
@GetMapping("/{id}")
public ResponseEntity<Book> getBookById(@PathVariable Long id) {
Optional<Book> book = bookService.getBookById(id);
return book.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
/**
* 添加图书
*/
@PostMapping
public ResponseEntity<Book> addBook(@RequestBody Book book) {
try {
Book savedBook = bookService.addBook(book);
return ResponseEntity.ok(savedBook);
} catch (Exception e) {
return ResponseEntity.badRequest().build();
}
}
/**
* 更新图书
*/
@PutMapping("/{id}")
public ResponseEntity<Book> updateBook(@PathVariable Long id, @RequestBody Book book) {
Book updatedBook = bookService.updateBook(id, book);
if (updatedBook != null) {
return ResponseEntity.ok(updatedBook);
}
return ResponseEntity.notFound().build();
}
/**
* 删除图书
*/
@DeleteMapping("/{id}")
public ResponseEntity<Map<String, String>> deleteBook(@PathVariable Long id) {
boolean deleted = bookService.deleteBook(id);
Map<String, String> response = new HashMap<>();
if (deleted) {
response.put("message", "图书删除成功");
return ResponseEntity.ok(response);
} else {
response.put("message", "图书不存在");
return ResponseEntity.notFound().build();
}
}
/**
* 根据书名搜索图书
*/
@GetMapping("/search/title")
public ResponseEntity<List<Book>> searchBooksByTitle(@RequestParam String title) {
List<Book> books = bookService.searchBooksByTitle(title);
return ResponseEntity.ok(books);
}
/**
* 根据作者搜索图书
*/
@GetMapping("/search/author")
public ResponseEntity<List<Book>> searchBooksByAuthor(@RequestParam String author) {
List<Book> books = bookService.searchBooksByAuthor(author);
return ResponseEntity.ok(books);
}
/**
* 根据分类查询图书
*/
@GetMapping("/category/{category}")
public ResponseEntity<List<Book>> getBooksByCategory(@PathVariable String category) {
List<Book> books = bookService.getBooksByCategory(category);
return ResponseEntity.ok(books);
}
/**
* 获取可借阅的图书
*/
@GetMapping("/available")
public ResponseEntity<List<Book>> getAvailableBooks() {
List<Book> books = bookService.getAvailableBooks();
return ResponseEntity.ok(books);
}
/**
* 综合查询图书
*/
@GetMapping("/search")
public ResponseEntity<List<Book>> searchBooks(
@RequestParam(required = false) String title,
@RequestParam(required = false) String author,
@RequestParam(required = false) String category,
@RequestParam(required = false) String status) {
List<Book> books = bookService.searchBooks(title, author, category, status);
return ResponseEntity.ok(books);
}
}