1. 引言

在日常开发中,经常会遇到这样一个需求:判断两个 List 是否相等——即它们是否包含相同的元素,并且元素顺序也完全一致。

List 是一种有序集合(ordered collection),这意味着元素的顺序是它语义的一部分。这一点非常关键,踩坑的同学往往是忽略了“顺序”这个前提。

我们先来看官方文档中对 List#equals 的定义:

两个列表当且仅当它们包含相同的元素且顺序相同时,才被认为是相等的。

✅ 这个定义保证了不同 List 实现类之间(比如 ArrayListLinkedList)也能正确地进行比较。

为了演示,我们定义以下三组测试数据:

List<String> list1 = Arrays.asList("1", "2", "3", "4");
List<String> list2 = Arrays.asList("1", "2", "3", "4");
List<String> list3 = Arrays.asList("1", "2", "4", "3");
  • list1list2:内容相同,顺序相同 → 应该相等
  • list1list3:内容相同,但顺序不同 → 不相等

接下来我们看看在主流测试框架中如何写出正确的断言。


2. 使用 JUnit 断言

如果你用的是 JUnit(通常是 JUnit 4),可以直接使用 Assert.assertEquals 来比较两个 List。

@Test
public void whenTestingForEquality_ShouldBeEqual() throws Exception {
    Assert.assertEquals(list1, list2);       // ✅ 相等
    Assert.assertNotSame(list1, list2);      // ✅ 不是同一个对象引用
    Assert.assertNotEquals(list1, list3);    // ✅ 顺序不同,不相等
}

⚠️ 注意:

  • assertEquals 调用的是 List 接口自身的 equals 方法,已经考虑了顺序。
  • assertNotSame 只是确认两个变量不是指向同一对象,避免误判引用相等为值相等。

简单粗暴,适合大多数单元测试场景。


3. 使用 TestNG 断言

TestNG 的用法和 JUnit 几乎一模一样,但注意导入的包不同:

import org.testng.Assert;

代码几乎可以完全复制:

@Test
public void whenTestingForEquality_ShouldBeEqual() throws Exception {
    Assert.assertEquals(list1, list2);       // ✅
    Assert.assertNotSame(list1, list2);      // ✅
    Assert.assertNotEquals(list1, list3);    // ✅
}

❌ 常见错误:把 JUnit 的 Assert 和 TestNG 的搞混,导致静态导入冲突或行为差异。记得检查 import!


4. 使用 AssertJ(推荐)

AssertJ 提供了更流畅、更具可读性的链式断言 API,强烈推荐在复杂逻辑或需要高表达力的测试中使用。

@Test
public void whenTestingForEquality_ShouldBeEqual() throws Exception {
    assertThat(list1)
      .isEqualTo(list2)           // ✅ 完全相等
      .isNotEqualTo(list3);       // ✅ 不相等

    // 也可以显式调用 equals 方法做布尔判断
    assertThat(list1.equals(list2)).isTrue();   // ✅
    assertThat(list1.equals(list3)).isFalse();  // ✅
}

✅ 优势:

  • 可读性强,一眼看出断言意图
  • 支持丰富的扩展断言(如 containsExactly, hasSize() 等)
  • 错误信息更友好,调试省时间

如果你的项目还没引入 AssertJ,真的建议加上。长期来看能显著提升测试代码质量。


5. 总结

判断两个 List 是否相等,核心在于理解 List#equals 的设计语义:

元素相同 + 顺序一致 = 相等

我们展示了三种主流测试框架下的写法:

框架 特点
JUnit 基础必备,简单直接
TestNG 注意包名别导错
AssertJ ✅ 推荐,表达力强,易维护

所有示例代码均可在 GitHub 获取:
👉 https://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-collections-list-2

📌 小贴士:如果不需要比较顺序,而是只关心“元素是否相同”,那应该用 Set 或手动排序后再比对。List 的顺序是它的灵魂,别轻易忽略。


原始标题:Check if Two Lists Are Equal in Java | Baeldung