首页 文章

Dart中不同Map实现之间有什么区别?

提问于
浏览
22

Dart有一个Map类型,有HashMap,LinkedHashMap和SplayTreeMap等实现 . 这些不同的Map实现之间有什么区别?

1 回答

  • 34

    Dart内置了对List,Set和Map等集合的支持 . Dart有不同的Map实现 . 了解实现之间的利弊可以帮助您做出明智的决策 .

    (注意:这是在Dart M3的时间写的,所以下面的内容可能与此时的文档不匹配 . )

    什么是 Map ?

    Map是一个关联容器,将键映射到值 . 键是唯一的,可以指向一个且只能指向一个值 . 键不能为null,但值可以为null .

    Map 文字

    Dart支持Map文字,如下所示:

    var accounts = {'323525': 'John Smith', '588982': 'Alice Jones'};
    

    规范说 Map 文字必须保持插入顺序 . 这意味着 accountsLinkedHashMap 的一个实例 .

    规范还说 Map 文字键必须是字符串 . 这可能会在将来改变 .

    新 Map ()

    Dart支持工厂构造函数,因此您可以像这样创建Map的新实例:

    var accounts = new Map();
    

    Map 类是抽象的,这意味着工厂构造函数实际上创建了 Map 的子类的实例 . 那么 accounts 的实际类型是什么?

    早期版本的Dart从 new Map() 构造函数创建了 HashMap 的新实例 . 但是,Dart bug 5803声明为了使 {}new Map 返回相同的类型, new Map 将很快返回 LinkedHashMap 的实例 .

    LinkedHashMap(或,InsertionOrderedMap)

    LinkedHashMap 按照插入的顺序迭代键和值 .

    注意:LinkedHashMap可能会重命名为InsertionOrderedMap . 按照Dart bug 2349进行操作 .

    这是一个例子:

    import 'dart:collection';
    main() {
      var ordered = new LinkedHashMap();
      ordered['32352'] = 'Alice';
      ordered['95594'] = 'Bob';
    
      for (var key in ordered.keys) {
        print(key);
      }
    
      // guaranteed to print 32352, then 95594
    }
    

    这是source code for LinkedHashMap . (如果此链接停止工作,可能是因为该类已重命名)

    HashMap

    HashMap无法保证维护插入顺序 . 当您遍历HashMap的键或值时,您不能指望某个订单 .

    使用hash table实现HashMap .

    以下是创建新HashMap的示例:

    import 'dart:collection';
    main() {
      var accounts = new HashMap();
    }
    

    如果您不关心维护插入顺序,请使用HashMap .

    这是source code of HashMap .

    SplayTreeMap

    展开树是一种自 balancer 二叉搜索树,具有附加属性,最近访问的元素可以再次快速访问 . 它在O(log(n))分摊的时间内执行插入,查找和删除等基本操作 .

    import 'dart:collection';
    main() {
      var accounts = new SplayTreeMap();
    }
    

    SplayTreeMap要求所有键都属于同一类型 .

    对于经常存储和访问的数据(如缓存),splay树是一个不错的选择 . 原因是他们使用树旋转将一个元素调到根,以便更频繁地访问 . 性能来自树的自我优化 . 也就是说,频繁访问的元素移动到更靠近顶部 . 但是,如果同时经常访问树,那么使用splay树映射几乎没有意义 .

    示例情况是调制解调器路由器以非常高的速率接收网络数据包 . 调制解调器必须决定哪个数据包进入哪个线路 . 它可以使用映射实现,其中键是IP,值是目标 . 对于此场景,splay树映射是一个不错的选择,因为大多数IP地址将被多次使用,因此可以从树的根目录找到它们 .

相关问题