Arrays.binarySearch 的高效依赖数组已升序、随机访问支持、查找逻辑与结构对齐三大前提;未排序数组返回值无规律;必须显式排序;降序需指定Comparator;返回值编码存在性与插入点;基本类型数组更安全高效;重复值只返其一,需额外处理边界。

Arrays.binarySearch 的高效不来自“魔法”,而来自三个硬性前提的严格满足:数组已升序、随机访问支持、查找逻辑与数据结构对齐。跳过任一环节,O(log n) 就会退化成不可靠的随机数。
必须升序,且升序不能靠“感觉”
它不校验排序状态,也不尝试修复。传入 [5, 1, 9, 3] 这样的数组,返回值可能是 -2、3 或 -1——全看中间值怎么“碰巧”比对,毫无规律可言。
- 排序动作必须显式执行:Arrays.sort(arr),且只做一次(除非数据变更)
- 数据库查出的数据,务必加 ORDER BY id ASC;前端传来的 ID 列表,接收后第一行就该是 Arrays.sort()
- 降序数组不能直接用,要配 Comparator.reverseOrder(),否则结果无效
返回值不是 true/false,是位置编码
它返回的整数同时承载“是否存在”和“应在哪儿”两层信息,误读就会漏判。
- ≥ 0:存在,数值就是下标,可直接 arr[index] 取值
- < 0:不存在,插入点 = -(返回值 + 1),例如返回 -4 → 插入点是 3
- 绝不能写 if (index == -1) 判断失败——未命中时可能返回 -1、-2、-100,只有 index < 0 才统一表示未找到
基本类型数组比包装类更稳更快
工号、订单号、时间戳这类纯数字场景,优先用 int[]、long[],而非 Integer[]、Long[]。
- int[] 内存连续、无 null 风险、无自动装箱开销
- Integer[] 中若混有 null,调用 binarySearch 时比较过程直接抛 NullPointerException
- key 是 int 类型却传给 Integer[] 数组,会触发隐式装箱,性能微损且增加空指针隐患
重复值只返其一,边界需另寻方案
数组 [2, 2, 2, 4, 6] 中查 2,可能返回 0、1 或 2 —— 它不承诺最左或最右,只保证“有”。需要全部索引或范围时,得组合使用:
- 先 binarySearch 确认存在,再从该位置向左右线性扫描相等元素(适合重复少、范围窄)
- 手写二分找左边界(mid 值等于 key 时不返回,继续向左收缩 high)和右边界(继续向右收缩 low)
- 高频多匹配查询,建议改用 Map<K, List<Integer>> 预建索引,而非反复扫描数组


















