submap返回的是原treemap的实时、可变、受约束的动态视图,非数据拷贝;其区间默认左闭右开,修改视图或原map会双向同步。

Java 中用 subMap 获取 TreeMap 的指定区间子视图,本质是获取一个**实时、可变、受原 Map 约束的视图**,不是拷贝数据。关键在于理解参数含义、开闭区间规则,以及视图的“联动性”。
subMap 方法签名与区间边界控制
TreeMap 提供两个主要重载版本:
-
subMap(K fromKey, K toKey):左闭右开区间[fromKey, toKey),要求fromKey ≤ toKey,否则抛IllegalArgumentException -
subMap(K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)(Java 12+):显式指定两端是否包含,更灵活
注意:所有键必须能被 TreeMap 的比较器比较,否则运行时抛 ClassCastException 或 IllegalArgumentException。
子视图是实时同步的活视图
返回的 SortedMap 是原 TreeMap 的**动态视图**:
- 在子视图中增删改,会直接影响原 Map;反之亦然
- 如果原 Map 中超出区间范围的键被删除,不影响子视图内容;但如果区间内键被删,子视图立刻反映
- 向原 Map 插入落在区间内的新键,子视图自动可见
例如:TreeMap<integer string> map = new TreeMap(); map.putAll(Map.of(1,"a",3,"c",5,"e",7,"g"));</integer>SortedMap<integer> sub = map.subMap(3, 6); // [3,6) → 包含键 3,5</integer>
执行 sub.put(4, "d") 后,map 中也会出现 4→"d";执行 map.remove(3),sub 中键 3 立即消失。
处理边界不存在时的行为
如果 fromKey 或 toKey 在原 Map 中不存在:
- 不影响方法调用——只要满足比较逻辑,视图仍按键的自然顺序截取
- 例如
map.subMap(2, 6)在键为 {1,3,5,7} 的 Map 中,仍返回键 3 和 5 对应的项(因为 2 5) - 但若
fromKey大于所有现有键(如subMap(10, 20)),返回空视图;若toKey小于最小键,抛IllegalArgumentException
安全使用的实用建议
- 调用前用
map.containsKey(fromKey)或map.ceilingKey(fromKey)预判边界是否存在(非必需,但便于调试) - 避免在多线程环境下直接操作子视图,除非原 Map 是线程安全的(如
ConcurrentSkipListMap)或已加锁 - 不需要副本时用
subMap;需要独立副本则调用new TreeMap(subMap(...)) - 注意
headMap(toKey)和tailMap(fromKey)是更简单的单边区间替代方案
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











