List.equals()要求元素数量相同且对应位置元素equals()相等,顺序敏感;Set.equals()只关心元素内容一致,顺序无关;自定义对象需重写equals()和hashCode();Arrays.equals()不适用于集合比较。

用 equals() 判断两个 List 是否相等
Java 的 List 接口明确重写了 equals(),它要求:元素数量相同、且每个位置上的元素都按顺序 equals() 相等。注意,这和 == 完全不同,后者只比较引用。
- 顺序敏感:
Arrays.asList(1, 2)和Arrays.asList(2, 1)不相等 - 允许
null:只要对应位置都是null或者非null且值相等即可 - 不要求底层实现类相同:
ArrayList和LinkedList可以互相比较
Lista = Arrays.asList("a", "b"); List b = new LinkedList<>(Arrays.asList("a", "b")); System.out.println(a.equals(b)); // true
用 equals() 判断两个 Set 是否相等
Set 的 equals() 只关心元素内容是否完全一致,不关心顺序或重复(本来就不允许重复)。只要两个集合包含的元素在 equals() 意义下一一对应,就返回 true。
- 顺序无关:
HashSet和TreeSet可直接比 - 要求双方都实现了
Set接口,否则可能调用的是Object.equals()(即引用比较) - 如果元素自身没正确重写
equals()和hashCode(),结果不可靠
Sets1 = new HashSet<>(Arrays.asList(1, 2, 3)); Set s2 = new TreeSet<>(Arrays.asList(3, 1, 2)); System.out.println(s1.equals(s2)); // true
遇到自定义对象时,必须重写 equals() 和 hashCode()
如果集合里存的是你写的类(比如 User),默认的 equals() 是引用比较,哪怕两个对象字段一模一样也会返回 false。
- 必须同时重写
equals()和hashCode(),否则HashSet/HashMap行为异常 - 推荐用 IDE 自动生成(如 IntelliJ 的
Alt+Insert→ “Generate…” → “equals() and hashCode()”) - 注意字段选择:只纳入影响“逻辑相等”的字段,比如
id或username,别把createTime这种非关键字段加进去
public class User {
private String username;
private int age;
// ... constructor, getters
@Override
public boolean equals(Object o) { /* generated */ }
@Override
public int hashCode() { /* generated */ }
}
不要用 Arrays.equals() 直接比较集合
Arrays.equals() 是为数组设计的,传入 List 或 Set 会调用 Object.equals(),结果几乎总是 false(除非是同一个对象引用)。
立即学习“Java免费学习笔记(深入)”;
- 常见误写:
Arrays.equals(list1, list2)—— 编译通过但语义错误 - 同样,
list1.toArray().equals(list2.toArray())也不行,因为数组的equals()仍是引用比较 - 真要转数组比,得用
Arrays.equals(arr1, arr2),且前提是先确保两者是同类型数组
集合相等这件事,表面看只是调个 equals(),但背后依赖的是接口契约、元素类型的实现质量,以及你有没有意识到顺序和重复对不同集合类型的意义差异。










