最有效的方法是直接动手练习字符串和自定义对象去重。先用200个随机两位字符串练HashSet去重,再通过重写hashCode()和equals()使Student等对象可去重,最后结合订单ID、手机号、IP地址等业务场景巩固,并注意避免只重写equals、使用可变字段、遍历错误及线程安全问题。

直接上手练最有效。重点不在背概念,而在理解“为什么重复不进去”和“怎么让自定义对象不重复”这两个核心问题。
从字符串去重开始练
这是最基础也最关键的一步。先别碰类,用字符串数组模拟真实场景:
- 创建一个含200个随机两位字符串的数组(比如"ab"、"x9")
- 用一个HashSet接收所有字符串,另一个HashSet专门存“第二次出现”的那些
- 关键操作:遍历数组时调用 set.add(s) == false 判断是否已存在
- 最后打印重复字符串种类数和具体值——结果应该稳定在几十种,不是0也不是200
让自定义对象也能去重
字符串能去重靠的是String自带的hashCode和equals。换成Student或Employee,就得自己写:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 定义Student类,含name和age两个字段
- 右键生成或手动重写hashCode():把name和age一起参与计算(推荐用Objects.hash(name, age))
- 同步重写equals():先判null和类型,再逐字段比较
- 测试:添加两个name="张三"、age=20的对象,HashSet大小应为1,不是2
结合业务场景练判断逻辑
脱离业务的练习容易忘。试试这几个小任务:
- 给定一批订单ID(字符串),快速找出哪些ID重复出现过
- 用户注册时,用HashSet缓存已注册手机号,每次add前用contains()拦截
- 解析日志行,提取所有出现过的IP地址,自动去重后统计总数
注意几个易错点
练的时候常卡在这几处:
- 只重写了equals没重写hashCode → 对象仍被当作不同元素加入
- 字段用了可变类型(如Date、StringBuilder)且没保证不可变 → 后续修改导致哈希值变化,集合行为异常
- 遍历时误用普通for循环(set.get(i)会报错)→ 只能用增强for或Iterator
- 多线程往同一个HashSet里add → 结果不可预测,需要加锁或换ConcurrentHashMap.keySet()

















