我想知道jsonEncode()
库中的函数dart:convert
是否完全可预测。也就是说,jsonEncode()
是否总是以相同的顺序编码Map
对象的键和值?
答案 0 :(得分:3)
答案是:这取决于。
作为一般规则,映射不存储任何顺序,并且对条目进行迭代会导致键值对以随机顺序返回。
具体细节要更深一些,还有一些实现细节需要考虑。在Dart中,Map
是抽象类,可以使用几种不同类型的Map
。
有HashMap
,它是Map
的默认实现。插入顺序不会保留,实际上,迭代期间返回条目的顺序是相当随机的。但是,仅当更改地图本身时,迭代顺序才会更改。这意味着只要您不从地图上添加或删除任何对象,迭代顺序每次都将是相同的顺序。
还有LinkedHashMap
类。与HashMap
不同,这种类型的地图确实保留插入顺序。当您遍历条目时,它们将以它们添加到地图的顺序出现。这样,在假定特定顺序时,可以在LinkedHashMap
上进行迭代是安全的。 (顺便说一下,这是使用地图文字(即{ 'a': 1 }
时创建的地图的类型。)
另一个示例是SplayTreeMap
。与其他两个不同,此映射根据键的compareTo
方法维护特定的顺序。也可以通过在创建地图时传入比较方法来覆盖此行为。
这都是假设我们从Map
的角度讨论迭代顺序。但是,从jsonEncode
的角度来看它可能是另一回事。 Dart尽可能委托一个特定于平台的本机JSON编码器,并且该编码器读取地图的方式与其实现建议的方式不同。也没有真正的方法来预测转换库将如何返回从JSON解析的映射。这不会以任何方式影响JSON-几乎所有的JSON编码器和解析器都将对JSON进行相同的处理,而与密钥的顺序无关。
简而言之,假设Map
的条目将保持可预测甚至一致的顺序通常是不明智的。如果需要固定顺序,则另一个数据结构可能是更好的调用。