java中arrays.binarysearch可通过预处理有序双数组实现轻量级区间匹配:用keys[]存左端点、rights[]存右端点,binarysearch定位后检查前一区间是否包含目标值,支持不重叠闭区间查询。

Java 中 Arrays.binarySearch 本身不直接支持区间匹配,但可借助其 O(log n) 查找能力 + 预处理有序结构,构建轻量、无额外依赖的区间路由表。核心思路是:将区间端点离散化为有序数组,用二分定位候选位置,再做常数次边界判断。
用左端点数组 + 显式区间检查实现最小内存模型
不封装对象、不建树、不缓存映射,仅用两个平行数组:
-
keys[]:所有区间的左端点(升序),类型为
long或int,避免装箱 - values[]:对应每个左端点的路由值(如整数 ID、短字符串、枚举常量)
查询时调用 Arrays.binarySearch(keys, target):
- 若返回 ≥ 0,说明 target 恰好等于某个左端点 → 直接命中
- 若返回负值 -(insertionPoint) - 1,则 insertionPoint 是第一个大于 target 的左端点下标;此时检查 insertionPoint - 1 对应的区间是否包含 target(即 target 或使用显式右端点数组)
用双数组存储左右端点,支持任意闭区间
若区间不等长或需精确覆盖(如 [10,15], [20,25], [30,40]),额外维护 rights[] 数组:
-
keys[i]和rights[i]构成第 i 个闭区间[keys[i], rights[i]] - 仍保持
keys[]严格升序(要求区间不重叠且左端点递增) - 查找逻辑:先
binarySearch(keys, target)得到插入点,再从max(0, insertionPoint - 1)开始最多检查前一个区间(因区间不重叠,至多一个可能匹配)
预排序与静态初始化,杜绝运行时扩容开销
路由表通常只读或极少更新,应在类加载或配置解析阶段一次性构建:
- 用
Arrays.sort对原始区间列表按左端点排序(O(n log n),仅一次) - 用
System.arraycopy复制到 final 字段数组,确保不可变 - 若配置来自 JSON/YAML,解析后立即归并重叠区间(可选),再生成 keys/rights 数组
示例片段:
static final long[] STARTS = {1L, 100L, 200L};static final long[] ENDS = {99L, 199L, 300L};
static final String[] ROUTES = {"A", "B", "C"};
static String lookup(long ip) {
int i = Arrays.binarySearch(STARTS, ip);
if (i >= 0) return ROUTES[i]; // 精确匹配左端点
i = -(i + 1) - 1; // 回退到前一个可能区间
if (i >= 0 && ip return "default";
}
规避常见陷阱:边界、重叠与空表安全
实际部署需加固边界逻辑:
- 插入点为 0 时,
i - 1会越界 → 必须加i >= 0判断 - 区间重叠时,binarySearch 只能定位首个左端点,需线性扫描后续(但违背低开销初衷)→ 建议预处理去重/合并
- 空数组需单独判空,
binarySearch在空数组上返回 -1,但插入点计算会出错 → 初始化时校验长度 - 若路由值为对象引用,注意 GC 压力;优先用 int/short/enum 表示路由标识
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











