顺序查找适用于数组无序、元素不可比较或仅查询一两次的场景,需手写for循环;Arrays.binarySearch要求有序且支持比较,否则返回插入点负值而非单纯“未找到”。

顺序查找:什么时候必须手写 for 循环
当数组没排序、元素类型不支持比较(比如自定义对象没实现 Comparable)、或者只查一两次时,Arrays.binarySearch 不但没用,还会出错。这时候老老实实遍历最稳。
- 常见错误现象:
Arrays.binarySearch在无序数组里返回负数,有人误以为“没找到”,其实它返回的是插入点的负值,跟是否真存在无关 - 使用场景:查
String[]里某个固定值;查int[]中第一次出现的位置;需要返回索引而非布尔结果 - 性能影响:时间复杂度 O(n),但常数小,小数组(
- 示例:
int index = -1;<br>for (int i = 0; i < arr.length; i++) {<br> if (arr[i] == target) {<br> index = i;<br> break;<br> }<br>}
Arrays.binarySearch:必须先排序,且只能用于基本类型或可比较对象
它不是“智能搜索”,只是在已排序前提下做二分——传进去乱序数组,结果完全不可信。
- 常见错误现象:
Arrays.binarySearch(new int[]{3,1,4}, 1)返回-1(实际应为 1),因为内部按有序假设计算插入位置 - 参数差异:对基本类型(
int[]、double[])直接用;对Object[],元素必须实现Comparable,或额外传Comparator - 兼容性注意:Java 8+ 支持
byte[]、short[]等所有基本类型重载;但Arrays.binarySearch(null, ...)直接抛NullPointerException - 示例:
int[] arr = {1, 3, 4, 7};<br>int pos = Arrays.binarySearch(arr, 4); // 返回 2<br>// 若查 5,返回 -4(-(插入点=3))
查不到时的返回值:负数不是“false”,是插入点编码
很多人把负数当成“不存在”就完事了,但这个值本身有结构,漏掉就浪费了信息。
- 返回规则:若找到,返回索引 ≥ 0;若未找到,返回
-(insertionPoint) - 1,其中insertionPoint是该值应插入的位置(保持升序) - 容易踩的坑:直接用
result 判断“不存在”,没问题;但若想算出插入位置,得写 <code>-(result + 1),不是-result - 实用技巧:配合
ArrayList插入时保持有序,用这个返回值能省一次查找 - 示例:
int[] a = {1, 3, 7};<br>int r = Arrays.binarySearch(a, 5); // r == -3<br>// 插入点 = -(r + 1) == 2 → 正确位置在索引 2(即 3 和 7 之间)
泛型数组和自定义对象:别绕开 Comparator 直接硬上
Arrays.binarySearch(Object[], T) 不会自动按字段比大小,没 Comparator 或 Comparable 就抛异常。
立即学习“Java免费学习笔记(深入)”;
- 常见错误现象:
Arrays.binarySearch(new String[]{"a","c","b"}, "b")可能返回负数——因为数组没排序,不是类型问题 - 必须同步两件事:先用
Arrays.sort(arr, comparator)排序;再用同个comparator调binarySearch - 性能提醒:排序是 O(n log n),如果只查一次,总代价远超顺序查找;频繁查询才值得预排序
- 示例:
Person[] people = {/* ... */};<br>Arrays.sort(people, Comparator.comparing(p -> p.age));<br>int idx = Arrays.binarySearch(people, target, Comparator.comparing(p -> p.age));
查数组元素这事,核心就两点:数据有没有序,以及你查几次。顺序查找看着土,但多数业务场景里它更直、更安全;二分不是银弹,它把“排序”这个隐性成本藏在了调用前——漏掉这步,结果就不可信。










