Arrays.binarySearch仅适用于已排序数组,需先用Arrays.sort或指定Comparator排序,返回值≥0表示找到索引,<0时插入点为-(返回值+1),对象查找必须统一Comparator,小数组线性查找更优。

Arrays.binarySearch 是 Java 中实现 O(log n) 索引查找的首选工具,但高效的前提是用对——它不排序、不校验、不宽容无序,只在已排序数组上“精准快切”。下面从实操角度讲清楚关键点。
必须先排序,且确保升序
binarySearch 不会检查数组是否有序,传入乱序数组时结果完全不可信。哪怕只差一个元素位置,二分逻辑就会一路错到底。
- 整数或基本类型数组:调用 Arrays.sort(arr) 即可,注意这会修改原数组
- 不想改原数组?用 arr.clone() 复制后再排序
- 对象数组(如 String[]、自定义类):必须用相同 Comparator 排序和查找,例如都用 Comparator.comparing(String::length)
- 降序数组不能直接用,需显式传入 Collections.reverseOrder()
正确解读返回值,别只认 -1
返回值不是布尔标志,而是带位置语义的整数:
- ≥ 0:找到,数值就是该元素在数组中的索引
- < 0:未找到,插入点 = -(返回值 + 1)(不是绝对值减 1)
- 例如返回 -4 → 插入点是 3;返回 -1 → 插入点是 0(应插在开头)
- 判断是否找到,唯一可靠写法是:if (index >= 0),而不是 if (index != -1)
按业务字段查找对象,别跳过比较器
如果工号、订单ID、用户名等封装在对象里,不能直接把对象数组和 int 值传进去——类型不匹配,编译可能过,运行必错。
- 方式一:让类实现 Comparable,在 compareTo() 中比业务字段(如 id)
- 方式二:用重载方法 Arrays.binarySearch(arr, key, comparator),comparator 明确指向业务字段,例如:Comparator.comparing(Order::getOrderId)
- 关键:排序时也得用同一个 comparator,否则查不到
避开常见坑,让查找真正高效
高效不只看算法复杂度,更要看整体开销:
- 小数组(比如长度 < 50)查一两次,线性遍历反而更快——binarySearch 常数因子略高,还依赖预排序
- 频繁查询同一组数据?排序一次,反复 binarySearch,这才是 O(log n) 的价值所在
- 用 int[] 而非 Integer[]:避免 null、装箱、GC 开销,工号/ID 类场景尤其明显
- 范围查找可用 binarySearch(arr, from, to, key),适合分段缓存或跳过无效区

















