arrays.binarysearch 返回值具有明确语义:≥0为存在时的索引,

Arrays.binarySearch 不是“查到了就完事”的黑盒工具,它返回的每个数字都携带明确的语义——索引位置或插入点编码。用对了,一次调用就能判断存在性、定位插入位、统计区间数量;用错了,比如数组未排序、越界传参、误判返回值,结果就不可靠。
必须满足的前提条件
二分查找不是万能加速器,它对输入有硬性要求:
- 数组必须已按升序排列(降序不支持,除非自定义 Comparator 且逻辑一致)
- 基本类型数组可直接使用;对象数组若含 null,且未提供 Comparator,运行时抛 NullPointerException
- 不能对 ArrayList 或 LinkedList 直接调用 Arrays.binarySearch —— 它只认数组,List 请用 Collections.binarySearch
- 调用前务必判空:数组为 null 会直接抛 NullPointerException
正确解读返回值
返回值不是简单“找到了”或“没找到”,而是结构化信息:
- ≥ 0:表示 key 确实存在,且返回值就是它在数组中的实际索引(从 0 开始)
- < 0:表示未匹配,但负数里藏着插入位置——插入点 = -(返回值) - 1
- 例如返回 -4,说明应插入到索引 3 的位置(因为 -(-4) - 1 = 3)
- 判断“是否存在”必须写 result >= 0,而不是 result != -1(未找到可能是 -2、-5、-10…)
子区间查找的边界逻辑
四参数重载版 binarySearch(array, fromIndex, toIndex, key) 使用左闭右开区间 [fromIndex, toIndex):
- 搜索范围是原数组中索引 fromIndex 到 toIndex - 1 的元素(toIndex 本身不参与)
- fromIndex 必须 ≥ 0,toIndex ≤ array.length,否则抛 IllegalArgumentException
- 插入点计算基于区间:key 小于区间所有元素 → 返回 -(fromIndex + 1);大于所有 → 返回 -(toIndex + 1)
- 返回的索引仍是**原数组下标**,不是子数组内部偏移
重复元素与边界定位
标准 binarySearch 对重复元素只保证返回“某个匹配位置”,不区分首次或末次出现:
- 需要找第一次出现位置?得手写 leftBound 模板:遇到相等时 high = mid - 1
- 需要找最后一次出现位置?得手写 rightBound 模板:遇到相等时 low = mid + 1
- 想统计某值出现次数?先用 leftBound 找左边界,再用 rightBound 找右边界,差值即频次
- 想查 [L, R) 区间内有多少元素?分别用 binarySearch 找 L 的插入点和 R 的插入点,相减即数量
不复杂但容易忽略











