collections.binarysearch 必须在升序排序前提下使用,否则结果不可靠;需避免字符串数字混排、浮点精度误差、null未处理等陷阱;仅适用于randomaccess集合;返回值含位置信息,负数表示插入点。

用 Collections.binarySearch 查找元素,不是“写了就能快”,而是“做对才真快”。它本身不排序、不校验、不兜底,只在你把前提全备好之后,给出一个精准下标或插入位置。
必须提前升序排序,且不能靠“看起来有序”
binarySearch 不检查顺序,哪怕只有一个元素错位,结果就不可信。常见陷阱包括:
- 数组或 List 来自接口或用户输入,没显式排序就直接查
- 字符串数字混排(如
"10"和2),自然排序会出错 - 浮点数因精度问题导致微小逆序,比如
0.1 + 0.2 != 0.3引起的排序偏差 - 含
null元素但 Comparator 没处理 null,运行时报NullPointerException
建议上线前加轻量断言:list.stream().reduce((a, b) -> a 或简单遍历校验。
Comparator 必须严格一致
排序用的 Comparator,查找时必须传同一个实例——不是“逻辑一样”,而是“同一个对象”。常见错误:
- 排序用
Comparator.comparing(Person::getAge),查找却传新构造的(a,b) -> a.getAge() - b.getAge() - 对降序数据误用自然排序查找:先
Collections.reverse(list),再直接binarySearch(list, key)→ 结果全错 - 正确做法:降序场景统一用
Collections.reverseOrder(),排序和查找都传它
别在 LinkedList 上硬套 binarySearch
binarySearch 内部依赖随机访问(get(i) 是 O(1)),而 LinkedList 的 get(i) 是 O(n)。实际性能可能比 ArrayList 线性扫描还慢 10 倍。
- 安全判断方式:
list instanceof RandomAccess,不满足就别用 -
Arrays.asList(...)返回的 List 支持 RandomAccess,可用 - 高频查找又需动态增删?换
TreeSet或TreeMap更合适
返回值要按语义解读,别只看正负
返回值不是“成功/失败”开关,而是带位置信息的编码:
- ≥ 0:找到,值就是索引
- 负数:没找到,插入点 =
-result - 1(不用手算,直接写这行) - 插入点范围一定是
[0, list.size()]:0 表示插最前,list.size()表示插最后 - 想查“首个 ≥ 目标”的位置(lower bound)?binarySearch 不直接支持,得自己封装或改用循环实现











