本文详解如何通过重写 equals() 方法,使泛型双向链表支持按对象特定属性(如 Voter 的 student ID)进行搜索,解决因默认引用比较导致的查找失败问题。
本文详解如何通过重写 `equals()` 方法,使泛型双向链表支持按对象特定属性(如 voter 的 student id)进行搜索,解决因默认引用比较导致的查找失败问题。
在使用泛型双向链表(DoublyLinkedList
要使 voterList.search(new Voter("", "", valueSearch)) 正确返回匹配的完整 Voter 对象,必须在 Voter 类中显式重写 equals() 方法,明确“两个 Voter 对象相等”仅需 studID 字段相同:
public class Voter {
private String username;
private String password;
private String studID;
// 构造函数、getter 等略...
@Override
public boolean equals(Object obj) {
if (this == obj) return true; // 引用相同,直接返回 true
if (obj == null || getClass() != obj.getClass()) return false; // 类型检查
Voter voter = (Voter) obj;
return Objects.equals(studID, voter.studID); // 仅比较 studID
}
@Override
public int hashCode() {
return Objects.hash(studID); // 与 equals 保持一致:仅基于 studID 计算哈希值
}
}✅ 关键说明:
- equals() 中必须使用 Objects.equals()(可安全处理 null),避免 studID.equals(...) 抛出 NullPointerException;
- hashCode() 必须与 equals() 逻辑一致(即若 a.equals(b) 为 true,则 a.hashCode() == b.hashCode()),这是 Java 合约要求,虽当前链表未用哈希结构,但属于良好实践,也为未来扩展(如迁移到 HashSet)预留兼容性;
- if (this == obj) 和类型检查是标准模板,提升性能与健壮性。
完成重写后,原驱动代码即可正常工作:
List<Voter> voterList = new DoublyLinkedList<>();
voterList.add(new Voter("Alice", "password1", "001"));
voterList.add(new Voter("Bob", "password2", "002"));
voterList.add(new Voter("Charlie", "password3", "003"));
String valueSearch = "003";
Voter found = voterList.search(new Voter("", "", valueSearch));
if (found != null) {
System.out.println("Found: " + found.getUsername() + ", ID: " + found.getStudID());
// 输出:Found: Charlie, ID: 003
} else {
System.out.println("Not found.");
}⚠️ 注意事项:
- 若 Voter 类后续需支持多字段联合查询(如“学号+姓名”),应同步更新 equals() 和 hashCode();
- 此方案依赖 studID 的唯一性——若存在重复学号,search() 将仅返回首个匹配节点(符合链表遍历逻辑);
- 如需更灵活的条件搜索(如模糊匹配、范围查询),建议将 search() 方法重构为接收 Predicate
或自定义 SearchCriteria,而非依赖 equals()。
通过精准控制对象相等语义,泛型容器便能无缝适配业务场景,这是面向对象设计中封装性与扩展性的典型体现。

















