arrays.binarysearch不实现查找逻辑,而是调用封装的二分查找;要求数组必须按同一comparator严格升序排列,且查找时必须传入相同comparator,key需能被安全比较,返回值为带位置语义的整数,重复元素仅返回某匹配位置。

Arrays.binarySearch 本身不“实现”查找逻辑,而是调用已封装的二分查找;它对自定义对象的支持完全依赖于你是否提供了明确、一致且已生效的排序依据。
数组必须按 Comparator 升序排好才能用
binarySearch 不检查顺序,只假设你传入的数组已严格按指定 Comparator 升序排列。如果没排序,或排序用的 Comparator 和查找时传入的不一致,结果毫无意义。
- 先调用 Arrays.sort(arr, comparator) —— 这一步不可省略,也不能用自然排序代替
- 查找时必须传入同一个 Comparator 实例(或语义等价的 lambda/方法引用)
- 常见错误:排序用了
Comparator.comparing(Person::getAge),查找却漏传 comparator,导致按自然序比较,抛 ClassCastException
key 参数要能被 Comparator 安全比较
传入的 key 不必是目标类型的完整实例,但必须能让 comparator 的 compare(T, T) 方法合法处理。
- 推荐做法:构造一个字段值匹配、其余字段可 null 或默认的占位对象,例如查年龄 ≥ 30,就 new Person(30, null)
- 避免强转风险:不要在 comparator 中写
(Person) o1,除非确保 key 一定是 Person 类型 - 若用 lambda 写 comparator,如
(p1, p2) -> Integer.compare(p1.age, p2.age),则两个参数都应为 Person,key 也应是 Person
返回值含义与实用转换
返回值不是布尔标识,而是带位置语义的整数,需正确解码:
- ≥ 0:找到,值即索引
- -(result + 1) 是插入点(第一个 ≥ key 的位置)
- 例如返回 -4 → 插入点为 3,说明索引 3 处的元素是第一个满足条件的候选
- 判断存在性,始终用 result >= 0,而非
result != -1
重复元素与边界定位限制
binarySearch 对重复值只保证返回“某个匹配位置”,不区分首尾。需要左边界(首个等于 key)或下界(首个 ≥ key),不能靠它直接实现:
- 确认存在后,若重复极少,可用 while 循环向左线性扫描找最左索引
- 追求 O(log n),需手写 lowerBound 风格二分,基于插入点逻辑扩展
- 不要试图用多次 binarySearch “逼近”边界——它不提供方向信息,也不支持 predicate











