Dart有一种映射类型,实现方式有HashMapLinkedHashMapSplayTreeMap.这些不同的 map 实现之间有什么区别?

推荐答案

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

(注:这是在DART M3前后编写的,因此以下内容可能与此时的文档不匹配.)

What is a Map?

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

Map Literals

Dart支持Map literals,如下所示:

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

该规范规定,映射文字必须保持插入顺序.这意味着accountsLinkedHashMap的一个实例.

规范还规定映射文字键必须是字符串.这在future 可能会改变.

new Map()

DART支持工厂构造函数,因此您可以创建一个新的Map实例,如下所示:

var accounts = new Map();

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

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

LinkedHashMap (or, InsertionOrderedMap)

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

Note: 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的键或值时,不能期望有特定的顺序.

HashMap是使用hash table实现的.

以下是创建新HashMap的示例:

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

如果您不关心保持插入顺序,可以使用HashMap.

这是source code of HashMap美元.

SplayTreeMap

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

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

SplayTreeMap要求所有键的类型相同.

展开树是存储和访问频繁的数据(如缓存)的理想 Select .原因是它们使用树旋转将元素带到根,以便更频繁地访问.性能来自于树的self 优化.也就是说,频繁访问的元素将移动到更靠近顶部的位置.但是,如果树周围的访问量相等,那么使用Splay树映射就没有什么意义了.

一个例子是以非常高的速率接收网络数据包的调制解调器路由.调制解调器必须决定哪个分组进入哪条线路.它可以使用键为IP、值为目的地的MAP实现.展开树映射对于此场景是一个很好的 Select ,因为大多数IP地址将被多次使用,因此可以从树的根找到这些地址.

Dart相关问答推荐

根据 Id 比较两个不同的 List

如何在 Dart 游戏中重复听按键?

Flutter 使用拖动和按钮单击扩展 TextField

dart:js 和 js 包有什么区别?

Flutter中包导入和普通导入有什么区别?

如何在没有 Scaffold.drawer 的情况下使用 Drawer?

结合freezed和hive

如何在 Flutter 中找出 URL 的有效性?

IOS中Webview Flutter字体太小

为什么 Dart 内置的 List 接口可以实例化?

无法将小部件标记为需要构建,因为框架已经在构建小部件的过程中

Flutter模糊叠加

如何在dart中获取 map 的键列表?

如何从目录中获取文件列表并将其传递给ListView?

在 Dart 中调用异步函数而不等待,例如启动一个线程

Dart 是否有断点语句?

Dart:如何在异步函数中管理并发

Dart 中使用的包命名约定是什么?

Dart 中的 Math.round() 在哪里?

Dart 语言中的 Console.log