treemap虽不直接支持区间检索,但基于红黑树的有序性,可通过submap、headmap、tailmap等视图方法高效实现按键范围查询;以左端点为键可快速筛选候选区间,再结合右端点判断完成重叠、覆盖等复杂查询。

TreeMap 本身不直接支持“区间检索”,但它基于红黑树实现、键天然有序,配合其 subMap、headMap、tailMap 等视图方法,可以高效完成按键范围的查询,是实现自动排序区间检索的常用选择。
理解 TreeMap 的排序与区间能力
TreeMap 的键必须实现 Comparable 或由 Comparator 定义顺序,插入时自动按升序(或自定义序)组织。它不存储“区间”对象,但可以把区间端点(如左边界)作为键,把整个区间信息(如 [left, right] 及关联值)作为值存入。只要键设计合理,就能利用有序性快速定位相关区间。
- 若按左端点排序,可用
subMap(leftLow, true, leftHigh, true)找出所有左端点落在某范围内的区间; - 若需查找“覆盖某点 x”的区间,则需额外逻辑(如遍历候选区间判断
left ≤ x ≤ right); - 若需“重叠某区间 [qL, qR]”的区间,可先用
subMap(qL, true, qR, true)快速筛出左端点在查询区间内的候选,再逐个检查是否重叠(即right ≥ qL)。
用左端点作键 + 自定义区间类
定义一个不可变区间类,并让其自然排序依据左端点:
public class Interval implements Comparable<interval> {
final int left, right;
final String value;
public Interval(int left, int right, String value) {
this.left = left;
this.right = right;
this.value = value;
}
@Override
public int compareTo(Interval o) {
return Integer.compare(this.left, o.left); // 按左端点升序
}
}</interval>
然后构建 TreeMap:
TreeMap<interval string> map = new TreeMap(); map.put(new Interval(1, 5, "A"), "data1"); map.put(new Interval(3, 8, "B"), "data2"); map.put(new Interval(10, 15, "C"), "data3");</interval>
此时调用 map.subMap(new Interval(2,0,""), true, new Interval(7,0,""), true) 就能拿到左端点 ∈ [2,7] 的区间(即 A 和 B)。
高效检索重叠区间的典型模式
单纯靠左端点筛选不够,真正“与 [qL, qR] 重叠”的条件是:interval.left ≤ qR && interval.right ≥ qL。TreeMap 可先缩小候选集,再过滤:
- 用
tailMap(new Interval(qL, 0, ""), true)获取所有左端点 ≥ qL 的区间(排除明显在查询区间左侧的); - 遍历该子映射,对每个
interval判断interval.right ≥ qL(即右端点不小于查询左边界); - 满足者即为重叠区间。平均性能优于全量扫描,尤其当区间稀疏或查询局部时。
替代方案:使用区间端点分别建索引
若查询频繁且维度多(如既要查覆盖点,又要查重叠、包含等),单靠一个 TreeMap 不够。常见优化是维护两个 TreeMap:
- 一个以左端点为键,存所有区间(用于快速找“起点在某范围内”的候选);
- 另一个以右端点为键,存所有区间(用于快速找“终点在某范围内”的候选);
- 联合查询时取交集或分别扫描后合并去重。
更进一步,可引入专门的区间树(如基于 JTS 或自行实现的 Augmented BST),但对多数业务场景,双 TreeMap 已足够平衡简洁性与性能。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











