面向对象案例

题目 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

相关推荐
Chris _data13 小时前
C# WinForms 后台轮询 Modbus 数据与 UI 更新实践
开发语言·ui·c#
奶人五毛拉人一块13 小时前
滑动窗口算法及习题讲解
数据结构·算法·滑动窗口·子数组
晚风叙码13 小时前
从0吃透C++入门|第一个程序、命名空间与缺省函数基础
开发语言·c++
yuhuofei202113 小时前
【Python入门】Python中的match-case语句用法
python
j_xxx404_13 小时前
Linux线程:核心机制与优雅的 C++ 封装实践|附源码
linux·运维·服务器·开发语言·c++·人工智能·ai
qingyulee13 小时前
机器学习概述、KNN算法
开发语言·python·机器学习
mohaoyuan13 小时前
软考架构师知识点汇总
开发语言·架构
yanghuashuiyue13 小时前
关于Eclipse和IDEA对比
java·ide·intellij-idea
月巴月巴白勺合鸟月半13 小时前
关于软件版本升级的故事
大数据