arrays.binarysearch 返回值直接指示插入位置:≥0表示已存在,负数时插入点为~returnval;插入需手动扩容移位,保持有序性,且比较逻辑须统一。

Arrays.binarySearch 的返回值不只是“找到”或“没找到”的开关,它天然携带插入位置信息——这使得它成为实现有序数组动态插入的理想搭档。关键不在于反复排序,而在于用一次查找,同时完成定位与准备。
插入前先查位置,避免重复遍历
调用 binarySearch 得到返回值后,无需额外扫描就能知道目标该放哪儿:
- 若返回值 ≥ 0:元素已存在,是否插入取决于业务逻辑(如去重则跳过)
- 若返回值为负数:说明不存在,且插入点 = ~returnVal(等价于 -(returnVal + 1))
- 插入点合法范围是 [0, array.length],包括插到末尾(插入点 = array.length)
真正插入时注意数组扩容与移位
Java 数组长度固定,binarySearch 不负责扩容。实际插入需手动处理:
- 若原数组有空余容量,用 System.arraycopy 将插入点右侧元素右移一位
- 若已满,需创建新数组(如 Arrays.copyOf(arr, arr.length + 1)),再复制元素并填入
- 插入点为 0 时,所有元素右移;插入点为 length 时,直接追加,无需移动
保持有序性,别绕开排序前提
动态插入多轮后,数组仍必须维持升序,否则后续 binarySearch 失效:
- 每次插入后,新数组仍是有序的——因为插入位置正是按大小关系算出的
- 不要在插入后重新全量排序(浪费 O(n log n)),binarySearch + 移位是 O(n),更轻量
- 若插入频次极高、查询极少,可考虑改用 TreeSet 或 TreeMap,它们自动维护有序
对象数组插入要统一比较逻辑
对 String[]、Integer[] 或自定义类数组,插入行为依赖 Comparator 的一致性:
- 排序时用了 Comparator.nullsFirst(String::compareTo),查找和计算插入点也必须传同一 Comparator
- 插入新元素时,确保它能被该 Comparator 正确比较(例如 null 元素需兼容)
- 子区间插入(如只在 [from, to) 中查插入点)返回的仍是全局索引,移位操作需基于该索引进行











