深入探索 Java:从基础到实战

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. 异常处理

核心概念:

异常: 程序执行过程中发生的事件,它中断了正常的指令流。通常代表错误(如文件找不到、除零、空指针访问、网络中断等)。

异常类型: 通常有层次结构(如 ExceptionRuntimeExceptionIOException 等)。

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. 枚举类型

特点:

声明的枚举值是该枚举类型的唯一实例

类型安全,避免使用整数或字符串常量带来的歧义和错误。

可以有自己的属性方法

常用于表示状态(如 ONOFF)、模式(如 MODE_AMODE_B)、类别(如 MONDAYTUESDAY, ..., 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() 等(从控制台读取用户输入)。

文件输入/输出:

        核心类:FileFileInputStream/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创建,拥有类定义的属性和方法。
  • 封装:通过访问控制(privatepublic)隐藏内部实现,仅暴露必要接口。

案例

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("裁判吹哨结束");
    }
}

总结对比

概念核心作用关键语法典型场景
类与对象封装数据与行为构造方法、成员变量 / 方法数据模型(用户、订单)
继承与多态代码复用、运行时行为差异化extendsabstract@Override插件系统、策略模式
接口实现定义契约,支持多继承implements、默认方法事件监听、服务提供者
封装与访问控制隐藏实现细节,保护数据privatepublicprotected安全敏感数据(账户余额)
静态成员类级别的属性和方法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是一个有序、可重复的集合,常用的实现类有ArrayListLinkedList

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用于存储键值对,常用的实现类有HashMapTreeMap

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是一个不允许重复元素的集合,常用的实现类有HashSetTreeSet

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(先进先出)原则,常用的实现类有LinkedListPriorityQueue

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图算法 - 使用邻接表表示图结构

在图算法中,使用MapList构建邻接表表示图:

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);
    }
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值