遍历两个Java列表时如何检查String相等性及列表一致性校验
实现两个排序列表的userId一致性检查
咱们先明确核心需求:两个已经按userId升序排好的列表,要先验证大小一致,再逐个对应检查元素的userId是否完全匹配,不匹配时抛出明确的异常。
步骤1:先检查列表大小
这一步你已经想到用简单的if语句实现,这里给出更健壮的写法:
if (classOneList.size() != classTwoList.size()) { throw new IllegalArgumentException(String.format("两个列表大小不匹配:classOneList有%d个元素,classTwoList有%d个元素", classOneList.size(), classTwoList.size())); }
用IllegalArgumentException符合Java的异常规范,同时异常信息带上具体的大小数值,方便快速定位问题。
步骤2:遍历两个列表并检查userId相等
Java没有直接支持同时遍历两个列表的增强for循环语法,但有几种实用的实现方式,这里按场景给你推荐:
方式1:普通for循环(最直观,适合随机访问列表如ArrayList)
因为列表已经按userId排序,索引对应的元素必然是要匹配的,直接按索引遍历最直接:
for (int i = 0; i < classOneList.size(); i++) { MyClass1 el1 = classOneList.get(i); MyClass2 el2 = classTwoList.get(i); // 重点:必须处理null值,避免NullPointerException String userId1 = el1.getUserId(); String userId2 = el2.getUserId(); if (userId1 == null) { if (userId2 != null) { throw new IllegalStateException(String.format("索引%d处userId不匹配:classOne的userId为null,classTwo的userId为%s", i, userId2)); } } else if (!userId1.equals(userId2)) { throw new IllegalStateException(String.format("索引%d处userId不匹配:classOne的userId为%s,classTwo的userId为%s", i, userId1, userId2)); } }
方式2:迭代器遍历(适合非随机访问列表如LinkedList)
如果你的列表是LinkedList这类非随机访问集合,用get(i)会频繁移动指针,效率很低,这时候用迭代器更合适:
Iterator<MyClass1> iter1 = classOneList.iterator(); Iterator<MyClass2> iter2 = classTwoList.iterator(); int index = 0; while (iter1.hasNext() && iter2.hasNext()) { MyClass1 el1 = iter1.next(); MyClass2 el2 = iter2.next(); // 复用上面的null检查和相等判断逻辑 String userId1 = el1.getUserId(); String userId2 = el2.getUserId(); if (userId1 == null) { if (userId2 != null) { throw new IllegalStateException(String.format("索引%d处userId不匹配:classOne的userId为null,classTwo的userId为%s", index, userId2)); } } else if (!userId1.equals(userId2)) { throw new IllegalStateException(String.format("索引%d处userId不匹配:classOne的userId为%s,classTwo的userId为%s", index, userId1, userId2)); } index++; } // 虽然前面已经检查过大小,但加一层保险防止意外情况 if (iter1.hasNext() || iter2.hasNext()) { throw new IllegalStateException("遍历过程中发现两个列表大小不一致"); }
方式3:Java 8+ Stream写法(更简洁)
如果想让代码更简洁,可以用IntStream生成索引流来遍历:
IntStream.range(0, classOneList.size()) .forEach(index -> { MyClass1 el1 = classOneList.get(index); MyClass2 el2 = classTwoList.get(index); String userId1 = el1.getUserId(); String userId2 = el2.getUserId(); if (userId1 == null) { if (userId2 != null) { throw new IllegalStateException(String.format("索引%d处userId不匹配:classOne的userId为null,classTwo的userId为%s", index, userId2)); } } else if (!userId1.equals(userId2)) { throw new IllegalStateException(String.format("索引%d处userId不匹配:classOne的userId为%s,classTwo的userId为%s", index, userId1, userId2)); } });
注意:Stream的forEach中只能抛出RuntimeException,如果需要抛自定义检查型异常,需要额外做包装处理。
额外优化建议
- 把userId匹配检查的逻辑抽成单独的工具方法,比如
private void checkUserIdMatch(MyClass1 el1, MyClass2 el2, int index),让代码更整洁易维护; - 如果业务允许,可以提前约定
userId不为null,减少null判断,但实际开发中还是建议保留null处理,避免空指针风险。
内容的提问来源于stack exchange,提问作者Dawid
相关产品推荐
相关产品推荐

