- Эта статья была разрешена для публикации в публичном аккаунте OpenFlutter.
Все версии, просьба указывать при перепечаткепроисхождение.
Dart имеет несколько встроенных коллекций, таких какSet,Listтак же какMap. Знание сильных и слабых сторон их реализации может помочь вам их использовать.
Эта статья демонстрируется в Dart 2.1.1. Если есть какие-либо ошибки, пожалуйста, поправьте меня.
Что такое карта
Карта — это ассоциативный контейнер, который сопоставляет ключи со значениями. Ключи уникальны и могут указывать на одно и только одно значение, но значения могут повторяться. ключ не может бытьnull, но значение может бытьnull.
Литерал карты
Дарт это поддержкаЛитерал карты, поэтому вы можете создать объект Map следующим образом:
var gifts = {
// Key: Value
'first': 'partridge',
'second': 'turtledoves',
'fifth': 'golden rings'
};
В спецификации упоминается, что литералы карты должны сохранять порядок вставки. это означаетgiftsдаLinkedHashMapпример. Давайте проверим:
print("type of gifts:${gifts.runtimeType}");
//type of gifts:_InternalLinkedHashMap<String, String>
new Map()
Dart поддерживает фабричные конструкторы, поэтому мы также можем создать карту следующим образом:
var gifts= new Map();
Начиная с Dart2, новый необязателен. Не упоминай об этом снова.
ОднакоMapЭто абстрактный класс, что означает, что приведенный выше код на самом деле является экземпляром, созданным подклассом Map. ТакgiftsКакой именно тип? Аналогично, напечатаем:
print("type of gifts:${gifts.runtimeType}");
// type of gifts:_InternalLinkedHashMap<dynamic, dynamic>
Фактически, в более ранних версиях Dartnew Map()фактически создаетHashMap. но, Dart bug 5803упоминается для того, чтобы сделать{}а такжеnew Map()возвращает тот же тип,new Mapскоро вернетсяLinkedHashMapпример.
LinkedHashMap
LinkedHashMapупорядочен, он повторяет ключи в порядке вставки:
var ordered = new LinkedHashMap();
ordered['32352'] = 'Alice';
ordered['95594'] = 'Bob';
for (var key in ordered.keys) {
print(key);
}
// 一定是先打印 32352, 然后打印95594
Изменение значения ключа не меняет порядок вставки ключей, но удаление, а затем добавление изменит порядок вставки:
var ordered = new LinkedHashMap();
ordered['32352'] = 'Alice';
ordered['95594'] = 'Bob';
ordered['45684'] = 'Kal';
for (var key in ordered.keys) {
print("仅遍历:$key");
}
ordered['95594'] = 'James';
for (var key in ordered.keys) {
print("改变一个值:$key");
}
ordered.remove('95594');
ordered['95594'] = 'Kobe';
for (var key in ordered.keys) {
print("改变一个值:$key");
}
Результат выглядит следующим образом:
仅遍历:32352
仅遍历:95594
仅遍历:45684
改变一个值:32352
改变一个值:95594
改变一个值:45684
删除后再添加:32352
删除后再添加:45684
删除后再添加:95594
HashMap
HashMapПорядок вставки данных не гарантируется. при пересеченииHashMap, порядок пар ключ-значение не гарантируется.
можно создать следующим образомHashMap:
import 'dart:collection';
main() {
var gifts= new HashMap();
}
Используйте, когда вас не волнует порядок пар ключ-значениеHashMap.
Исходный код HashMap находится здесь.
SplayTreeMap
Splay tree (разделенное дерево) — это самобалансирующееся бинарное дерево поиска с быстрым доступом к последним посещенным элементам. Он может выполнять операции вставки, поиска и удаления за O(log n).
import 'dart:collection';
main() {
var gifts= new SplayTreeMap();
}
SplayTreeMap требует, чтобы все ключи были одного типа:
var splayTreeMap = SplayTreeMap();
splayTreeMap["1"] = "s";
splayTreeMap[1] = "2";
Приведенный выше синтаксис кода хорош, но не разрешен во время выполнения:
type 'int' is not a subtype of type 'String' of 'other'
Для часто хранимых и доступных данных (таких как кеши),SplayTreeMapхороший выбор. Причина в том, что они используют вращение дерева, чтобы привести элемент к корню для более частых посещений. Производительность исходит из самооптимизации дерева. То есть часто используемые элементы перемещаются ближе к верху. Однако, если к дереву часто обращаются одновременно, используйтеSplayTreeMapпочти бессмысленно.
Например, модем-маршрутизатор получает сетевые пакеты с очень высокой скоростью. Модем должен решить, какой пакет идет по какой линии. Этого можно добиться с помощью карты, где ключом является IP-адрес, а значением — линия назначения. В этом случае,SplayTreeMap— хороший выбор, так как большинство IP-адресов будут использоваться несколько раз, поэтому их можно найти в корне дерева.
заключительные замечания
В этой статье кратко объясняются различия между несколькими картами в Dart.Хотя она не объясняет конкретную реализацию, я надеюсь, что она может быть полезной. Наша группа связи QQ: 892398530.