行业资讯 2025年08月6日
0 收藏 0 点赞 827 浏览 3356 个字
摘要 :

文章目录 1.使用Common Collections4的CollectionUtils.isEqualCollection() 2.使用Hamcrest的Matchers.containsInAnyOrder() 3.使用AssertJ的containsExactlyInAnyOrde……




  • 1.使用Common Collections4的CollectionUtils.isEqualCollection()
  • 2.使用Hamcrest的Matchers.containsInAnyOrder()
  • 3.使用AssertJ的containsExactlyInAnyOrderElementsOf() API
  • 4.纯粹的Java或JUnit
  • 5.结论

学会如何在Java中比较两个List列表,以便判断两个列表包含完全相同的项目,而且每个列表项在两个列表中的出现次数必须相等

1.使用Common Collections4的CollectionUtils.isEqualCollection()

要使用此API,请在Maven存储库中包含最新版本的commons-collections4。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version>
</dependency>

isEqualCollection() API在两个列表完全包含相同元素且具有完全相同基数(即:一个元素在两个列表中的出现次数完全相同)时返回true。

List<String> list = Arrays.asList(\"a\", \"b\", \"c\");
List<String> equalList = Arrays.asList(\"b\", \"c\", \"a\");
List<String> unequalList = Arrays.asList(\"d\", \"c\", \"a\");
assertTrue(CollectionUtils.isEqualCollection(list, equalList));
assertFalse(CollectionUtils.isEqualCollection(list, unequalList));

我们可以验证在比较列表时也考虑了基数。

assertFalse(CollectionUtils.isEqualCollection(
    Arrays.asList(\"a\", \"a\", \"b\"),
    Arrays.asList(\"a\", \"b\", \"b\")));
assertTrue(CollectionUtils.isEqualCollection(
    Arrays.asList(\"a\", \"b\", \"b\"),
    Arrays.asList(\"a\", \"b\", \"b\")));

默认情况下,使用equals()方法比较列表项。有时,我们从不同的来源接收列表,而列表项可能不包含默认相等规则所需的所有字段。我们还可以通过提供Equator接口的自定义实现来提供自定义相等逻辑。

在以下示例中,我们正在比较String实例,忽略大小写。请注意,使用Map实例检查基数,因此有必要将相同的项目转换为相同的键。在这种情况下,所有键将转换为大写字符串。

class StringCaseEquator implements Equator<String> {
  public boolean equate(String s1, String s2) {
    return s1.equalsIgnoreCase(s2);
  }
  @Override
  public int hash(String s) {
    return s.toUpperCase().hashCode();
  }
}
assertTrue(CollectionUtils.isEqualCollection(
    Arrays.asList(\"a\", \"b\"),
    Arrays.asList(\"A\", \"B\"),
    new StringCaseEquator()));

2.使用Hamcrest的Matchers.containsInAnyOrder()

要使用此API,请在Maven存储库中包含最新版本的hamcrest-all。

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
</dependency>

containsInAnyOrder() API创建了一个用于可迭代对象的无序匹配器,该匹配器匹配两个列表的元素,忽略列表中元素的顺序。对于积极匹配,两个列表必须具有相同的大小,因此我们不需要显式比较大小。

List<String> list = Arrays.asList(\"a\", \"b\", \"c\");
List<String> equalList = Arrays.asList(\"b\", \"c\", \"a\");
assertThat(list, Matchers.containsInAnyOrder(equalList.toArray()));

此解决方案不支持列表项的自定义相等逻辑。

3.使用AssertJ的containsExactlyInAnyOrderElementsOf() API

首先添加Maven存储库中最新版本的assertj-core。

<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.16.1</version>
</dependency>

containsExactlyInAnyOrderElementsOf()验证第一个列表包含第二个列表的所有元素,并且每个元素以任意顺序出现相同数量的次数。

List<String> list = Arrays.asList(\"a\", \"b\", \"c\");
List<String> equalList = Arrays.asList(\"b\", \"c\", \"a\");
org.assertj.core.api.Assertions.assertThat(list)
        .containsExactlyInAnyOrderElementsOf(equalList);

任何额外出现的项目都将导致断言失败。

4.纯粹的Java或JUnit

如果我们不想使用任何第三方库,可以使用List.remove()方法来设计我们自己的解决方案。在以下代码中,我们正在迭代第一个列表,并从第二个列表中删除当前项目的第一个出现。迭代完成后,第二个列表必须为空。请注意,此方法使用ArrayList类上提供的remove() API。因此,如果使用不可变列表,请考虑将它们包装在ArrayList实例中。

static boolean compareListsIgnoringOrder(ArrayList list1, ArrayList list2) {
  if (list1 == null || list2 == null) return false;
  if (list1.size() != list2.size()) return false;
  for (Object o : list1) {
    list2.remove(o);
  }
  if (list2.size() != 0) return false;
  return true;
}
List<String> firstList = Arrays.asList(\"a\", \"b\", \"c\", \"c\");
List<String> secondList = Arrays.asList(\"b\", \"c\", \"a\", \"c\");
assertTrue(compareListsIgnoringOrder(new ArrayList(firstList), new ArrayList<>(secondList)));

5.结论

在单元测试中,需要比较两个Java列表的顺序是否被忽略,这是一个常见的需求,其中两个列表来自不同的来源,我们必须检查两个列表是否具有相同的元素,而不考虑它们在列表中的顺序。本教程展示了使用Apache Common Collections4、Hamcrest、AssertJ和纯粹的Java API的示例,可用于JUnit断言语句。

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/9361.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号