在Java开发中,业务系统经常会把用户ID、订单编号这类业务主键存储在有序数组中,当需要查询某个主键对应的索引时,如果采用线性遍历的方式,时间复杂度是O(n),数据量大的时候性能会明显下降。而Arrays类的binarySearch()方法基于二分查找实现,时间复杂度仅为O(log n),能够快速完成定位。

Arrays.binarySearch() 基本使用规则
该方法属于java.util.Arrays类,是静态方法,调用时不需要创建Arrays实例。它有两个常用的重载形式,分别用于查找基本类型数组和对象数组中的目标元素。
查找基本类型有序数组
对于int、long、double等基本类型的数组,要求数组必须是升序排列的,否则查找结果是不确定的。方法签名如下:
public static int binarySearch(int[] a, int key)
其中a是待查找的有序数组,key是要查找的目标业务主键,返回值是目标元素的索引,如果没找到则返回负数。
查找对象类型有序数组
对于对象数组,数组中的元素必须实现了Comparable接口,并且按照自然升序排列,或者调用带Comparator参数的重载方法,按照指定的比较规则升序排列。方法签名如下:
public static int binarySearch(T[] a, T key, Comparator<? super T> c)
业务主键查找代码示例
下面以用户ID这个业务主键为例,演示如何在有序的int数组中查找目标ID的索引:
import java.util.Arrays;
public class BinarySearchDemo {
public static void main(String[] args) {
// 模拟存储用户ID的有序数组,假设已经按升序排列
int[] userIds = {1001, 1003, 1005, 1007, 1009, 1011};
// 要查找的目标业务主键
int targetUserId = 1007;
// 调用Arrays.binarySearch()查找索引
int index = Arrays.binarySearch(userIds, targetUserId);
if (index >= 0) {
System.out.println("业务主键" + targetUserId + "的索引为:" + index);
} else {
// 没找到时的返回值处理
System.out.println("业务主键" + targetUserId + "不存在,插入点索引为:" + (-index -1));
}
}
}
上述代码中,userIds数组是升序排列的用户ID集合,调用binarySearch方法查找1007,最终会返回索引3,符合预期结果。
返回值含义解析
Arrays.binarySearch()的返回值有两类情况:
- 如果数组中包含目标业务主键,返回该主键在数组中的索引,索引从0开始计数。
- 如果数组中不包含目标业务主键,返回一个负数,这个负数的绝对值减1,就是该主键如果插入数组时应该放置的位置索引,也就是插入点。
比如上面的例子中,如果查找1006,数组中没有这个元素,返回的会是-4,因为1006应该插入到索引3的位置,符合(-(-4)-1)=3的计算逻辑。
使用注意事项
在使用该方法查找业务主键时,需要注意以下几点:
- 待查找的数组必须是升序排列的,如果数组是降序或者无序的,查找结果没有意义,可能返回错误的索引或者找不到存在的元素。
- 如果数组中有多个相同的业务主键,方法不能保证返回的是第一个还是最后一个匹配的索引,只会返回其中一个存在的索引。
- 对于对象数组的查找,如果使用自定义比较器,必须保证比较器的规则和数组的排序规则一致,否则会出现查找错误。
- 该方法只适用于数组结构,如果存储业务主键的是List集合,需要先转换为数组,或者使用Collections.binarySearch()方法。
性能对比
我们可以通过简单的测试对比线性查找和二分查找的性能差异,假设有序数组长度为100000,查找位于数组末尾的元素:
import java.util.Arrays;
public class PerformanceTest {
public static void main(String[] args) {
int[] arr = new int[100000];
for (int i = 0; i < arr.length; i++) {
arr[i] = i * 2;
}
int target = 199998;
// 线性查找测试
long start1 = System.nanoTime();
int linearIndex = -1;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
linearIndex = i;
break;
}
}
long end1 = System.nanoTime();
System.out.println("线性查找耗时:" + (end1 - start1) + "纳秒");
// 二分查找测试
long start2 = System.nanoTime();
int binaryIndex = Arrays.binarySearch(arr, target);
long end2 = System.nanoTime();
System.out.println("二分查找耗时:" + (end2 - start2) + "纳秒");
}
}
实际运行时可以看到,二分查找的耗时远远低于线性查找,数据量越大,性能差距越明显,这也体现了使用Arrays.binarySearch()在有序数组中定位业务主键的优势。
JavaArrays_binarySearch有序数组二分查找业务主键修改时间:2026-06-12 15:33:31