You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于二分搜索实现的contains方法无法正确检测重复元素?

嘿,我来帮你揪出问题的根源,顺便给你个更省心的解决方案!

问题排查与修复

你的自定义去重逻辑里藏着两个关键问题,才导致了元素误判和重复残留的情况:

1. 二分搜索的结果判断完全搞反了

Collections.binarySearch的返回规则可不像你想的那样简单,它的返回值逻辑是:

  • 找到元素时:返回该元素在有序列表里的非负索引
  • 没找到元素时:返回-(插入位置) - 1(这个插入位置是指把新元素插进去还能保持列表有序的位置)

你现在的判断代码是:

if (index == -1) {
    return false;
} else {
    return true;
}

这就会导致:

  • 只有当元素不存在且刚好要插在列表最开头时(返回-1),才会判定为“不存在”
  • 其他所有情况(不管元素真的存在,还是不存在但插在别的位置)都会被判定为“存在”,这直接让大量不存在的元素被错误拦截,而本该拦截的重复元素却可能漏过。

正确的判断逻辑应该是直接检查索引是否大于等于0:

return index >= 0;

2. 列表只排了一次序,添加元素后就乱了

你只在最开始对列表做了一次快速排序,但每次往里面加新元素后,列表的有序性就被破坏了!而二分搜索的前提是列表必须严格按照指定的Comparator保持有序,不然搜索结果完全是瞎蒙的。

比如你排序后是[A,B,C],加个D还好,要是加个B,列表就变成[A,B,C,B],这时候再用二分搜索找元素,结果肯定错得离谱,这也是为什么你的列表里还会有重复元素的核心原因。


更省心的替代方案:用TreeSet自动搞定去重+排序

与其自己手动折腾排序和二分搜索,不如直接用Java集合框架里的TreeSet,它天生就是干这个的:

  • 会按照你指定的Comparator自动保持元素有序
  • 自动去重,重复元素加不进去
  • 查找和添加的效率都是O(log n),比你手动实现的靠谱多了

给你个示例代码:

// 先定义好卡片的比较器
Comparator<Card> cardComparator = (card1, card2) -> card1.getName().compareTo(card2.getName());

// 初始化TreeSet,把比较器传进去
Set<Card> uniqueCardSet = new TreeSet<>(cardComparator);

// 直接加元素就行,重复的会自动被过滤
uniqueCardSet.add(new Card("TheCard"));
uniqueCardSet.add(new Card("TheOtherCard"));
uniqueCardSet.add(new Card("TheCard")); // 这个重复的加不进去,不用自己判断

// 如果最后需要List类型,直接转一下就行
List<Card> uniqueCardList = new ArrayList<>(uniqueCardSet);

这样既不用自己写容易出错的判断逻辑,也能保证效率和正确性,完美解决你的问题~

内容的提问来源于stack exchange,提问作者Josh Hunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:54:45