TreeMap遍历本质是中序遍历红黑树,天然按键升序;四种方式:keySet()、values()、entrySet()(最常用)、Iterator(唯一安全修改方式);遍历时仅允许entry.setValue()或Iterator.remove(),禁止直接put/remove。

TreeMap 遍历本质是遍历红黑树的中序序列
TreeMap 底层是红黑树,所以它的 keySet()、entrySet()、values() 返回的集合天然按 key 升序排列。遍历时不需要额外排序,但也不能用基于哈希的随机访问方式(比如通过索引),所有遍历都必须走迭代器或增强 for 循环。
四种常用遍历方式及适用场景
实际开发中主要用以下四种,区别在于是否需要 key、value 或 entry,以及是否需修改映射:
- 只读 key:用
for (K key : map.keySet())—— 简洁,但每次map.get(key)是 O(log n) 查找,不推荐频繁取 value - 只读 value:用
for (V value : map.values())—— 无法反查 key,且顺序由 key 决定,不是 value 自身大小顺序 - 同时读 key 和 value(最常用):
for (Map.Entry—— 一次拿到键值对,O(1) 访问,性能最优e : map.entrySet()) - 需要修改 value 或删除当前项:必须用
Iterator,调用> iterator.remove()安全删除,否则抛ConcurrentModificationException
遍历时修改元素的正确姿势
TreeMap 不允许在遍历中直接调用 map.put() 或 map.remove(),否则触发快速失败机制。唯一安全的修改方式是:
- 仅更新 value:通过
entry.setValue(newVal)—— 这不会破坏红黑树结构 - 删除当前项:必须用
Iterator.remove(),不能用map.remove(key) - 插入新 key:禁止在遍历中执行,应先收集待插入项,遍历结束后统一
putAll()
TreeMapmap = new TreeMap<>(); map.put("a", 1); map.put("b", 2); Iterator > it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry e = it.next(); if (e.getKey().equals("a")) { e.setValue(99); // ✅ 允许 it.remove(); // ✅ 安全删除 } }
注意 reverseOrder() 和自定义 Comparator 的影响
TreeMap 构造时若传入 Comparator(包括 Collections.reverseOrder()),遍历顺序完全由该比较器决定,和自然顺序无关。此时:
立即学习“Java免费学习笔记(深入)”;
-
firstKey()/lastKey()返回的是比较器下的极值,不是字典序首尾 - 使用
subMap(from, to)等范围视图时,from/to 必须符合同一比较逻辑,否则行为未定义 - 遍历性能仍是 O(n log n),但常数略高(每次比较调用额外函数)
如果只是临时逆序遍历,更轻量的做法是用 new TreeMap(Collections.reverseOrder()).putAll(original),而不是在原 map 上强加 comparator 后再遍历。










