如何对比两个不同类型对象列表的Id和Title字段值是否相等
两种场景下的实现方案
1. AssertJ 便捷实现(推荐)
不需要提前转换为Map,直接通过字段提取+元素比较即可完成校验,代码非常简洁:
顺序完全匹配校验
import static org.assertj.core.api.Assertions.assertThat; // 写法1:字段名字符串形式,无需写getter assertThat(aObjectList) .extracting("aId", "aTitle") .containsExactlyElementsOf( assertThat(bObjectList) .extracting("bId", "bTitle") .getActual() ); // 写法2:类型安全写法(需提前实现类的getter方法) assertThat(aObjectList) .extracting(ObjectA::getAId, ObjectA::getATitle) .containsExactlyElementsOf( bObjectList.stream() .map(b -> org.assertj.core.groups.Tuple.tuple(b.getBId(), b.getBTitle())) .toList() );
元素无序校验
如果只要求两个列表的id+title组合集合完全匹配,不需要对应顺序,把上面的containsExactlyElementsOf替换为containsExactlyInAnyOrderElementsOf即可。
2. 纯JDK Stream 实现方案
如果项目没有引入AssertJ依赖,可以用Stream转换为公共比较结构后直接对比:
import java.util.stream.Collectors; import java.util.function.Function; // JDK16+ 可以用record定义公共比较键,低于16版本可以用AbstractMap.SimpleEntry或自定义类 record CompareKey(String id, String title) {} // 转换两个列表为比较键列表 List<CompareKey> aCompareList = aObjectList.stream() .map(item -> new CompareKey(item.aId, item.aTitle)) .toList(); List<CompareKey> bCompareList = bObjectList.stream() .map(item -> new CompareKey(item.bId, item.bTitle)) .toList(); // 顺序匹配校验 assertEquals(aCompareList, bCompareList); // 无序匹配校验(兼容重复元素) assertEquals( aCompareList.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())), bCompareList.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) );
补充说明
你提到的转List<Map<String, String>>的方案也可以实现,只是代码冗余度更高,没有上面两种方案简洁高效,该方式的示例如下:
List<Map<String, String>> aMapList = aObjectList.stream() .map(a -> Map.of("id", a.aId, "title", a.aTitle)) .toList(); List<Map<String, String>> bMapList = bObjectList.stream() .map(b -> Map.of("id", b.bId, "title", b.bTitle)) .toList(); assertEquals(aMapList, bMapList);
内容的提问来源于stack exchange,提问作者Ip Man
相关产品推荐
相关产品推荐

