java集合比较依赖元素重写的equals和hashcode方法,未重写则默认引用比较;需遵守jdk规范并确保二者一致;可用ide生成或lombok注解;contains、remove等操作及集合间equals均基于此实现。

Java 中用 equals 比较集合元素是否相等,关键不在于“怎么调用”,而在于“对象自身是否正确重写了 equals(和 hashCode)”。集合(如 ArrayList、HashSet、LinkedHashSet)内部依赖元素的 equals 方法做逻辑相等判断,若未重写,就只能靠默认的引用比较(==),导致看似相同的内容也被判为不等。
确保自定义类正确重写 equals 和 hashCode
这是最根本的前提。JDK 对 equals 有明确规范:自反性、对称性、传递性、一致性、对 null 的处理。同时,只要两个对象 equals 返回 true,它们的 hashCode 必须相同(反之不必须)。
- 用 IDE(如 IntelliJ IDEA)快捷生成:右键 → Generate → Equals and hashCode,勾选参与比较的字段
- 若用 Lombok,直接加
@EqualsAndHashCode注解(注意:默认包含所有非静态非瞬态字段;如有特殊需求,可用include/exclude指定) - 避免手写错误:比如只重写
equals忘了hashCode,或hashCode计算未覆盖所有equals中用到的字段
使用 contains、remove、indexOf 等方法时,依赖的就是元素的 equals
这些操作本质上遍历集合并调用每个元素的 equals 方法与目标比较。只要你的对象重写了正确的 equals,就能自然生效。
-
list.contains(new Person("Alice", 25))→ 若Person正确重写了equals,即使该对象不在原 list 中,只要姓名年龄相同,就返回true -
set.remove(new Person("Bob", 30))→ 在HashSet中,先通过hashCode定位桶,再用equals精确匹配删除 - 注意:
ArrayList.indexOf()是顺序遍历 +equals,HashSet.contains()是哈希定位 +equals,但底层都离不开你写的equals
比较两个集合是否“内容相等”,用 Collection.equals() 而非 ==
直接用 list1.equals(list2) 就能判断两个 List 是否含相同元素且顺序一致(按 equals 逐个比);set1.equals(set2) 则只看元素是否完全相同(不关心顺序)。
- 它不是比较引用,而是语义相等:要求大小相同,且每个位置(List)或每个元素(Set)都能用
equals匹配上 - 前提仍是:集合中元素类型已正确定义
equals。例如两个ArrayList<string></string>可以直接比,因为String已重写;但两个ArrayList<myobj></myobj>若MyObj没重写,就只会比引用 - 不要用
==比集合内容,那只是判断是否同一个对象
特殊场景:需要按特定规则比较?考虑使用 Comparator 或 Stream filter
如果“相等”的含义是动态的、上下文相关的(比如只比 ID、忽略大小写、或按某个字段近似相等),就不适合修改类的 equals(会破坏通用语义),而应改用外部逻辑。
- 查找满足条件的元素:
list.stream().filter(p -> p.getId() == targetId).findFirst() - 自定义去重:
list.stream().collect(Collectors.toCollection(() -> new TreeSet(Comparator.comparing(Person::getName)))) - 手动遍历比较:
for (Person p : list) { if (p.getName().equalsIgnoreCase("alice")) ... }
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











