binarysearch要求列表严格有序,否则结果不可靠;返回值≥0表示找到并给出索引,负数表示未找到并隐含插入位置;仅适用于随机访问快的arraylist,不推荐linkedlist。

它不自己排序,也不验证顺序——只在你确认排好序的前提下,用二分法快速定位。关键不在“怎么调用”,而在“为什么必须先排序”和“返回值到底在说什么”。
查找前必须确保 List 已严格有序
binarySearch 不会检查列表是否有序,它直接按二分逻辑往下算。如果 list 是乱的,结果可能偶然对、更多时候错,且无法复现。
- 自然序(如 Integer、String):先调用
Collections.sort(list),再用无参binarySearch(list, key) - 自定义顺序(如按长度、按价格):排序和查找都必须用同一个
Comparator,缺一不可 - 反转后不能直接查:调用
Collections.reverse()后列表变降序,此时若仍用默认 binarySearch,相当于拿升序算法查降序数据,结果必然错误
返回值不是布尔值,而是位置线索
它返回的整数同时承载“是否存在”和“该在哪”的信息:
- ≥ 0:找到目标,数值就是它在 list 中的索引(比如返回 2,说明元素在第 3 个位置)
- 负数:没找到,但告诉你“如果插入,应该放在哪”——公式是 -(插入位置) - 1
- 例如返回 -4,说明插入点是索引 3(因为 -4 = -(3) - 1),插入后仍能保持升序
底层就是标准二分,三变量推进
它内部维护 left、right、mid 三个边界,每轮只比一次 mid 位置的元素:
- nums[mid] == target → 直接返回 mid
- nums[mid]
- nums[mid] > target → 目标在左半段,right = mid - 1
- 直到 left > right,区间为空,判定不存在,按规则算出插入点
性能与适用边界要心里有数
虽是 O(log n),但实际效果依赖 List 实现:
- 推荐用于
ArrayList:支持随机访问,mid 取值快 - 慎用于
LinkedList:每次取 nums[mid] 都得从头遍历,退化成 O(n log n),得不偿失 - 重复元素存在时,返回任意一个匹配位置,不保证是第一个或最后一个
- 需要找左边界或范围查询?binarySearch 不够用,得自己写 lowerBound 或换用 Guava/Apache Commons











