You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart语言中HashMap与SplayTreeMap的区别是什么?

Dart中HashMap与SplayTreeMap的核心区别

1. 底层实现与顺序保证

  • HashMap 基于哈希表实现,不保证键值对的遍历顺序,你之前的示例中输出有序只是巧合(整数键的哈希值刚好和自身值相关,导致存储位置连续)。
  • SplayTreeMap 基于伸展树(自平衡二叉树)实现,始终按键的自然顺序(或自定义比较器)维护排序,遍历输出一定是有序的。

2. 性能特性

  • HashMap:增删改查操作的平均时间复杂度为O(1),最坏情况O(n),适合对性能要求高、无需有序遍历的场景。
  • SplayTreeMap:所有操作的时间复杂度为O(log n),但会将最近访问的节点移到树的根位置,频繁访问的元素会有更快的访问速度,适合需要有序遍历或频繁访问热点元素的场景。

3. 键的约束

  • HashMap 的键需要实现==运算符和hashCode方法,默认的内置类型(如int、String)已经满足。
  • SplayTreeMap 的键需要支持比较:要么实现Comparable接口(内置类型默认支持),要么在初始化时传入自定义的比较器函数。

凸显差异的示例代码

用字符串键或非连续整数键就能看到明显区别:

void main() {
  // 用字符串键测试HashMap的无序性
  HashMap hashMap = HashMap();
  hashMap['z'] = 'Zebra';
  hashMap['a'] = 'Apple';
  hashMap['m'] = 'Monkey';
  hashMap['b'] = 'Banana';
  print('HashMap 输出(无序): $hashMap');

  // SplayTreeMap始终有序
  SplayTreeMap splayTreeMap = SplayTreeMap();
  splayTreeMap['z'] = 'Zebra';
  splayTreeMap['a'] = 'Apple';
  splayTreeMap['m'] = 'Monkey';
  splayTreeMap['b'] = 'Banana';
  print('SplayTreeMap 输出(有序): $splayTreeMap');

  // 非连续整数键的情况
  HashMap hashMapInt = HashMap();
  hashMapInt[10] = 'Ten';
  hashMapInt[2] = 'Two';
  hashMapInt[5] = 'Five';
  hashMapInt[1] = 'One';
  print('\nHashMap(非连续整数键): $hashMapInt');

  SplayTreeMap splayTreeMapInt = SplayTreeMap();
  splayTreeMapInt[10] = 'Ten';
  splayTreeMapInt[2] = 'Two';
  splayTreeMapInt[5] = 'Five';
  splayTreeMapInt[1] = 'One';
  print('SplayTreeMap(非连续整数键): $splayTreeMapInt');
}

示例输出(HashMap的顺序不固定,每次运行可能不同)

HashMap 输出(无序): {z: Zebra, a: Apple, m: Monkey, b: Banana} // 实际顺序可能变化
SplayTreeMap 输出(有序): {a: Apple, b: Banana, m: Monkey, z: Zebra}

HashMap(非连续整数键): {10: Ten, 2: Two, 5: Five, 1: One} // 顺序不固定
SplayTreeMap(非连续整数键): {1: One, 2: Two, 5: Five, 10: Ten}

内容的提问来源于stack exchange,提问作者Israr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 20:25:32