Arrays.binarySearch要求数组必须升序,返回值≥0为索引、<0时-(返回值+1)为插入点;需预排序、慎用类型与集合、注意重复值和线程安全。

Arrays.binarySearch 不是“搜一下就行”的工具,它是一把双刃剑——用对了快如闪电,用错了结果全错。核心就两点:数组必须升序排好,返回值要按规则解读。
必须先排序,否则结果毫无意义
binarySearch 不检查也不排序,它只假设你传进来的是升序数组。乱序数组调用后,返回值既不是真实索引,也不符合插入点逻辑,纯属随机数。
- 基本类型数组(如 int[]):调用 Arrays.sort(arr) 一次即可,后续多次查找复用
- 对象数组(如 String[]):确保元素实现 Comparable,或显式传 Comparator
- 不确定是否有序?加断言:assert isSorted(arr) : "Array must be sorted";(调试阶段特别有用)
- 动态生成的数据(如用户输入、API 返回),务必在首次查找前完成排序
读懂返回值:正数是位置,负数藏插入点
返回值不是简单的“找到/没找到”,而是带位置语义的整数:
- ≥ 0:表示找到,数值就是该元素在数组中的索引(从 0 开始)
- < 0:表示未找到,此时 -(返回值 + 1) 就是应插入的位置索引
- 例如返回 -4 → 插入点为 3;返回 -1 → 应插在开头(索引 0);返回 -7(数组长为 6)→ 应插在末尾(索引 6)
- 判断是否存在,务必写 if (index >= 0),别用 index != -1 —— 未找到时可能是 -2、-5、-10…
灵活用区间和自定义比较器
不止查整个数组,还能精准控制范围和比较逻辑:
- 查子区间:用 binarySearch(arr, fromIndex, toIndex, key),注意是左闭右开 [fromIndex, toIndex)
- 区间内必须升序,但不要求整个数组都参与——适合分页数据、时间范围筛选等场景
- 按非自然顺序查找:传 Comparator,比如 Comparator.comparing(String::length) 或 Collections.reverseOrder()
- 对象数组含 null?必须提供支持 null 的 Comparator,否则抛 NullPointerException
避开常见坑:类型、集合、重复值
几个高频出错点,直接列清:
- int[] 和 Integer[] 别混用:前者走基本类型重载,后者走对象版,自动装箱可能引发空指针
- 别对 List 直接用 Arrays.binarySearch:它是数组专用。List 要用 Collections.binarySearch(list, key),且推荐 ArrayList(LinkedList 效率极低)
- 重复元素只保证返回“其中一个”:不承诺首/尾位置。需左边界?得配合手动向左扫描,或改用 stream filter(小数据量)
- 多线程或频繁更新场景慎用:排序状态易被破坏。更稳妥选 TreeSet / TreeMap,自动维护有序+O(log n) 查找

















