Java如何不使用嵌套循环校验不同列表中是否存在相同标识对象
解决方案
原嵌套循环的时间复杂度为O(n*m),数据规模较大时性能损耗明显,以下两种方案都可以实现相同逻辑,无需显式编写for循环和break语句。
方案1:HashSet优化方案(推荐,大数据量下性能优势显著)
先遍历一次clients列表提取标识存入HashSet,后续查询复杂度为O(1),整体时间复杂度降至O(n+m):
import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; // 提取所有Client关联的标识,仅需遍历一次clients Set<标识字段实际类型> clientIdentifierSet = clients.stream() .map(client -> client.getTire().getIdentifier()) .collect(Collectors.toSet()); // 直接判断是否存在匹配项,anyMatch匹配到首个符合条件的元素时自动终止 boolean exists = persons.stream() .anyMatch(person -> clientIdentifierSet.contains(person.getIdentifier()));
注:代码中Set<标识字段实际类型>的泛型需替换为你业务中identifier字段的真实类型。
方案2:纯Stream嵌套匹配(适合小数据量场景)
如果数据规模不大,不需要额外优化性能,可以直接用Stream嵌套匹配简化写法:
import java.util.Objects; boolean exists = persons.stream() .anyMatch(person -> clients.stream() .anyMatch(client -> Objects.equals(person.getIdentifier(), client.getTire().getIdentifier())) );
注意事项:
- 上述两种方案中
anyMatch自带短路特性,匹配到符合条件的元素后会立刻停止遍历,和原代码中break的效果完全一致- 原代码使用
==判断标识符是否相等,若标识符为引用类型(如String、Long),==是地址比较,建议替换为Objects.equals做值比较,同时可以规避空指针问题
内容的提问来源于stack exchange,提问作者Kapio
相关产品推荐
相关产品推荐

