Arrays.binarySearch高效前提为数组已升序排序且查找逻辑与排序依据一致;返回值≥0表示找到并给出索引,<0时-(返回值+1)为插入位置;需按类型选重载方法,重复元素需额外处理。

Arrays.binarySearch 不是“一调就灵”的黑盒,它高效的前提是严格满足条件——数组必须已升序排序,且查找逻辑与排序依据完全一致。用对了,O(log n) 响应飞快;用错了,返回值毫无意义,还难排查。
必须先排序,且不能跳过验证
binarySearch 从不检查数组是否有序,也不会抛异常提醒你。传入乱序数组,结果可能是正数(误报存在)、负数(但插入点无效),甚至每次运行都不一样。
- 升序查找:调用 Arrays.sort(arr) 预处理(注意原数组会被修改)
- 不想改原数组:用 arr.clone() 复制后再排序
- 降序需求:显式传入 Collections.reverseOrder() 作为 Comparator
- 调试阶段建议加断言:assert isSorted(arr) : "Array not sorted";(可自定义 isSorted 方法简单遍历校验)
读懂返回值,别只看是不是 -1
返回值不是布尔标识,而是带位置语义的整数:
- ≥ 0:找到,数值就是索引(例如返回 2 表示第 3 个元素匹配)
- < 0:未找到,此时 -(返回值 + 1) 才是应插入的位置索引
例如返回 -4 → 插入点为 3;返回 -1 → 应插在开头(索引 0) - 判断是否存在,务必写 result >= 0,而不是 result != -1
按场景选对重载方法
Java 提供多组重载,选错会导致编译通过但逻辑崩溃:
- int[]、double[] 等基本类型数组:用对应类型签名,如 Arrays.binarySearch(int[], int)
- String[] 或实现了 Comparable 的对象数组:用 Arrays.binarySearch(Object[], Object)
- 需自定义比较规则(如按字符串长度、忽略大小写):用三参数版本,传 Comparator
- 只查某一段(比如跳过前 2 个、只查后半段):用四参数版本,注意 toIndex 是开区间
重复元素和边界查找要另做处理
binarySearch 只返回“其中一个”匹配索引,不保证是第一个或最后一个:
- 想获取所有相同元素的索引?先 binarySearch 定位一个位置,再向左右线性扫描相等值
- 想快速找左边界(首个出现位置)?不能直接靠 binarySearch,需手写二分逻辑或借助辅助方法
- 高频查重复项?考虑预构建 Map<T, List<Integer>>,以空间换时间
- 动态增删+查重?TreeSet 或 Guava 的 TreeMultiset 更合适

















