Arrays.binarySearch不会报错但结果不可信,因其完全依赖数组已升序排列的前提:中点比较失去方向指引,乱序时arr[mid]无法划分有效区间,导致搜索路径错误、返回值无意义,官方明确将其列为硬性契约而非可选优化。

Arrays.binarySearch 不会报错,但传入未排序数组时,结果完全不可信——它不是“找不准”,而是“逻辑崩塌”。根本原因在于:这个方法从不验证顺序,只按升序假设推进每一步比较。
中点比较失去方向指引
二分查找每次取中点后,靠 target 与 arr[mid] 的大小关系 决定搜左还是搜右。这个判断成立的前提是:左半段所有元素 ≤ arr[mid],右半段所有元素 ≥ arr[mid]。
- 数组乱序时,arr[mid] 不再是分界基准,比较结果会误导搜索路径
- 例如 {5, 1, 8, 3} 查 3:第一次取索引 1 的元素 1,误判 3 > 1 就只搜 {8, 3},直接跳过真实位置
- 哪怕只有一个逆序对,也可能让算法舍弃含目标的区间
返回值看似有规律,实则无意义
未排序时的返回值不遵循任何可靠规则,常见表现包括:
- 查存在的元素,返回负数(伪失败)
- 查不存在的元素,偶然返回正索引(伪命中),但无法复现
- 返回的负数如 -4,本应表示插入点为 3,但在未排序数组上该值毫无语义
它不检查、不提醒、不修复
Arrays.binarySearch 是纯契约型方法:
- 源码中无排序校验逻辑,不会抛异常,也不会打印警告
- 小数组(JDK8 中长度 < 21)甚至改用线性扫描,但依然依赖“已排序”前提
- 官方文档明确写有 “the array must be sorted”,这是正确性底线,不是性能建议
降序或自定义顺序也必须严格匹配
升序不是唯一选项,但切换顺序必须显式且一致:
- 降序数组不能直接调用 Arrays.binarySearch(arr, key),必须同时满足:用 Collections.reverseOrder() 排过序,且查找时传入同一 Comparator
- String[] 或 Integer[] 含 null 时,若未传 Comparator,运行时直接抛 NullPointerException
- Comparator 版本要求 key 和所有元素都能被该比较器安全处理,否则可能 ClassCastException

















