Java中Set如何忽略顺序判断整数列表类型元素是否重复
问题原因说明
Java中List接口的equals()和hashCode()是严格按有序规则实现的,只有两个列表的元素顺序、元素值完全一致时才会判定为相等,你遇到的现象就是该特性导致的。
解决方案
方案1:保留List<List<Integer>>原结构实现去重
不需要修改外层容器类型,新增两个工具方法做校验即可:
import java.util.ArrayList; import java.util.Collections; import java.util.List; public class ListUtils { // 对比两个列表是否元素相同(忽略顺序) private static boolean isEqualIgnoreOrder(List<Integer> a, List<Integer> b) { if (a.size() != b.size()) { return false; } List<Integer> sortedA = new ArrayList<>(a); List<Integer> sortedB = new ArrayList<>(b); Collections.sort(sortedA); Collections.sort(sortedB); return sortedA.equals(sortedB); } // 往外层列表添加元素时自动去重(忽略顺序) public static void addIgnoreDuplicateOrder(List<List<Integer>> outerList, List<Integer> newList) { for (List<Integer> existing : outerList) { if (isEqualIgnoreOrder(existing, newList)) { // 存在重复直接返回,不执行添加 return; } } outerList.add(newList); } }
使用时直接调用ListUtils.addIgnoreDuplicateOrder(你的外层列表实例, 要添加的子列表)即可。
方案2:搭配Set实现高性能去重
如果列表数量较多,每次遍历校验性能不足,可以自定义包装类重写equals和hashCode规则,适配HashSet的去重逻辑:
import java.util.List; import java.util.Objects; import java.util.stream.Collectors; public class OrderIgnoredIntList { private final List<Integer> rawList; public OrderIgnoredIntList(List<Integer> rawList) { this.rawList = rawList; } public List<Integer> getRawList() { return rawList; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OrderIgnoredIntList that = (OrderIgnoredIntList) o; return Objects.equals( rawList.stream().sorted().collect(Collectors.toList()), that.rawList.stream().sorted().collect(Collectors.toList()) ); } @Override public int hashCode() { return Objects.hash(rawList.stream().sorted().collect(Collectors.toList())); } }
使用时可以通过Set<OrderIgnoredIntList>批量去重,去重后调用getRawList()提取原始列表存入List<List<Integer>>即可。
如果你的业务场景允许子列表的重复元素被去重,也可以直接将子列表转成HashSet后再存入外层Set,性能更高,但该方案会丢失子列表的重复元素信息,仅适合无重复元素的场景使用。
内容的提问来源于stack exchange,提问作者PC5
相关产品推荐
相关产品推荐

