- Эта статья была разрешена для публикации в публичном аккаунте 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.