firstKey()和lastKey()仅返回TreeMap中全局最小和最大键,不支持子区间极值查询;需用subMap()构造区间视图后再调用,或直接使用ceilingKey()/floorKey()等方法。

TreeMap 的 firstKey() 和 lastKey() 不是用来“获取数组范围”的,它们只返回当前所有键中按排序规则确定的**最小键**和**最大键**——也就是整个映射的极值界限,而非某个子区间的边界。想拿“某段范围内的极值”,不能只靠这两个方法,得配合区间视图操作。
firstKey() 和 lastKey() 的真实作用
它们是快速获取全局排序后首尾键的轻量方法:
-
firstKey()返回红黑树最左节点的键(时间复杂度接近 O(1),因内部有缓存引用) -
lastKey()返回最右节点的键 - 两者都只返回 K 类型的键,不带值;要取对应 value,需额外调用
get(firstKey()) - 空 TreeMap 调用会直接抛
NoSuchElementException,不是返回 null
想获取“某范围内的极值”?得先定义范围
如果你本意是找「大于等于 10 且小于等于 100 的所有键中的最小/最大键」,firstKey() 和 lastKey() 无能为力——它们只管全集。你需要:
- 用
subMap(fromKey, true, toKey, false)构造闭开区间视图(如含 10、不含 101) - 再对这个子视图调用
firstKey()/lastKey(),才得到该范围内的极值键 - 例如:
treeMap.subMap(10, true, 100, true).firstKey()就是 ≥10 且 ≤100 的最小键
安全使用的关键细节
避免运行时异常和逻辑偏差:
- 始终检查非空:
if (!map.isEmpty()) { key = map.firstKey(); } - 更推荐用
firstEntry()/lastEntry():空时返回 null,且一步拿到键值对,避免两次查找 - 自定义 Comparator 会彻底改变“最小/最大”的含义——比如倒序比较器下,
firstKey()实际是数值最大的那个键 - 键类型必须可比较(实现
Comparable或提供Comparator),否则行为未定义
替代方案:更直接的区间极值查询
如果只是临时查“≥X 的最小键”或 “≤Y 的最大键”,不用构造子视图:
-
map.ceilingKey(x)→ 大于等于 x 的最小键(不存在则 null) -
map.floorKey(y)→ 小于等于 y 的最大键 -
map.higherKey(x)→ 严格大于 x 的最小键 -
map.lowerKey(y)→ 严格小于 y 的最大键
这些方法天然处理空情况,也无需担心子视图生命周期或修改影响原 map。










