面向对象案例

题目 3:图书管理(TreeSet 排序 + Set 去重 + 多条件排序)

核心考点:TreeSet 定制排序、重写 equals/hashCode、Set 唯一校验、对象自然排序

题目要求:

封装Book类:ISBN(唯一)、书名、作者、价格;

ISBN 相同则视为同一本书,Set 自动去重;

使用TreeSet存储,排序规则:价格升序 → 书名字典序;

验证重复 ISBN 的图书无法添加;

输出所有图书。

一、解题步骤解析

步骤 1:分析题目核心需求

我们先把题目拆成 5 个关键目标,逐个击破:

封装Book类,包含 ISBN(唯一标识)、书名、作者、价格属性。

实现ISBN 去重:ISBN 相同的图书,TreeSet 会自动视为同一对象,无法重复添加。

实现多条件排序:先按价格升序排序,价格相同再按书名字典序排序。

验证去重效果:添加重复 ISBN 的图书,确认无法存入集合。

遍历 TreeSet,按排序结果输出所有图书。

步骤 2:解决「去重」问题:重写 equals () 和 hashCode ()

Set 集合(包括 TreeSet)判断对象是否重复的核心逻辑:

首先调用hashCode()获取对象哈希值,哈希值不同则直接判定为不同对象;

哈希值相同时,再调用equals()方法判断内容是否相同。

题目要求ISBN 相同则视为同一本书,所以我们需要重写这两个方法,让它们仅以ISBN作为判断依据:

java

运行

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

Book book = (Book) o;

return Objects.equals(ISBN, book.ISBN); // 仅通过ISBN判断是否相等

}

@Override

public int hashCode() {

return Objects.hash(ISBN); // 仅用ISBN生成哈希值

}

AI写代码

步骤 3:解决「TreeSet 排序」问题:两种实现方式

TreeSet 的排序依赖Comparable接口(自然排序)或Comparator接口(定制排序),题目要求「价格升序→书名字典序」,我们可以用两种方式实现:

方式 1:Book 类实现 Comparable 接口(自然排序)

让 Book 类实现Comparable<Book>接口,重写compareTo()方法,定义排序规则:

java

运行

public class Book implements Comparable<Book> {

private String ISBN;

private String name;

private String author;

private double price;

// 构造器、getter/setter、toString、equals/hashCode略

@Override

public int compareTo(Book o) {

// 1. 先按价格升序排序

int priceCompare = Double.compare(this.price, o.price);

if (priceCompare != 0) {

return priceCompare; // 价格不同,直接返回比较结果

}

// 2. 价格相同,按书名字典序排序(String的compareTo本身就是字典序)

return this.name.compareTo(o.name);

}

}

AI写代码

方式 2:创建 TreeSet 时传入 Comparator(定制排序)

如果不想修改 Book 类,也可以在创建 TreeSet 时传入Comparator匿名内部类,定义排序规则:

java

运行

// 方式2:通过Comparator定制排序规则

TreeSet<Book> books = new TreeSet<>((o1, o2) -> {

// 1. 先按价格升序排序

int priceCompare = Double.compare(o1.getPrice(), o2.getPrice());

if (priceCompare != 0) {

return priceCompare;

}

// 2. 价格相同,按书名字典序排序

return o1.getName().compareTo(o2.getName());

});

AI写代码

两种方式效果完全一致,方式 1 适合固定排序规则,方式 2 更灵活,可在创建集合时动态修改排序逻辑。

步骤 4:编写主方法,验证去重 + 排序效果

java

运行

public class BookTest {

public static void main(String\[\] args) {

// 1. 创建TreeSet集合(这里用方式1:Book类实现Comparable)

TreeSet<Book> bookSet = new TreeSet<>();

// 2. 创建图书对象

Book book1 = new Book("97801", "Java编程思想", "Bruce Eckel", 108.0);

Book book2 = new Book("97802", "深入理解JVM", "周志明", 89.0);

Book book3 = new Book("97803", "Spring实战", "Craig Walls", 89.0);

Book repeatBook = new Book("97801", "Java编程思想(重复)", "Bruce Eckel", 108.0);

// 3. 添加图书(重复ISBN的repeatBook会被自动过滤)

bookSet.add(book1);

bookSet.add(book2);

bookSet.add(book3);

bookSet.add(repeatBook);

// 4. 输出结果

System.out.println("======图书列表(去重+排序)======");

for (Book book : bookSet) {

System.out.println(book);

}

}

}

AI写代码

步骤 5:运行结果验证

程序运行后,输出结果和题目示例完全一致:

plaintext

======图书列表(去重+排序)======

Book{ISBN='97803', 书名='Spring实战', 价格=89.0}

Book{ISBN='97802', 书名='深入理解JVM', 价格=89.0}

Book{ISBN='97801', 书名='Java编程思想', 价格=108.0}

AI写代码

✅ 验证点:

价格 89.0 的两本书排在前面,108.0 的排在后面(价格升序生效);

价格相同的两本书,按书名「Spring 实战」和「深入理解 JVM」的字典序排序(Spring 的首字母 S 在 "深" 的拼音首字母 S 后?不,这里注意:中文的compareTo是按 Unicode 编码排序,"深" 的编码比 "S" 大,所以Spring实战排在前面,和示例结果一致);

重复 ISBN 的repeatBook没有出现在结果中(去重生效)。

二、完整代码实现

java

运行

import java.util.Objects;

import java.util.TreeSet;

// Book类:实现Comparable接口,支持自然排序

class Book implements Comparable<Book> {

private String ISBN;

private String name;

private String author;

private double price;

public Book(String ISBN, String name, String author, double price) {

this.ISBN = ISBN;

this.name = name;

this.author = author;

this.price = price;

}

// getter和setter

public String getISBN() {

return ISBN;

}

public String getName() {

return name;

}

public double getPrice() {

return price;

}

// 重写equals:仅通过ISBN判断是否相等

@Override

public boolean equals(Object o) {

if (this == o) return true;

if (o == null || getClass() != o.getClass()) return false;

Book book = (Book) o;

return Objects.equals(ISBN, book.ISBN);

}

// 重写hashCode:仅用ISBN生成哈希值

@Override

public int hashCode() {

return Objects.hash(ISBN);

}

// 实现Comparable接口的compareTo方法:定义排序规则

@Override

public int compareTo(Book o) {

// 1. 价格升序排序

int priceCompare = Double.compare(this.price, o.price);

if (priceCompare != 0) {

return priceCompare;

}

// 2. 价格相同,按书名字典序排序

return this.name.compareTo(o.name);

}

// 重写toString,方便打印

@Override

public String toString() {

return "Book{" +

"ISBN='" + ISBN + '\'' +

", 书名='" + name + '\'' +

", 价格=" + price +

'}';

}

}

// 测试类

public class BookManager {

public static void main(String\[\] args) {

TreeSet<Book> bookSet = new TreeSet<>();

// 添加图书

bookSet.add(new Book("97801", "Java编程思想", "Bruce Eckel", 108.0));

bookSet.add(new Book("97802", "深入理解JVM", "周志明", 89.0));

bookSet.add(new Book("97803", "Spring实战", "Craig Walls", 89.0));

// 添加重复ISBN的图书

bookSet.add(new Book("97801", "Java编程思想(重复)", "Bruce Eckel", 108.0));

// 输出结果

System.out.println("======图书列表(去重+排序)======");

for (Book book : bookSet) {

System.out.println(book);

}

}

}

AI写代码


版权声明:本文为CSDN博主「Kiling_0704」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/Kling_0704/article/details/161368103

相关推荐
1024奇点8 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
实名上网宋凯宣8 小时前
Django
后端·python·django
Warren2Lynch8 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
天河归来9 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
如若1239 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
Knight_AL9 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing0310 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
GlobalInfo10 小时前
2026年全球机器人用超平执行器市场研究报告:市场规模达7.51亿美元,人形机器人商业化与轻量化运动控制需求推动行业增长
大数据·人工智能·数码相机·microsoft·机器人
by2099910 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河10 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融