Основы Dart 2.x (Коллекции)

04.06.2020
This article was written for an older Flutter version and is being updated. Some code may not compile on the current version.

Во многих приложениях требуется создавать группы связанных объектов и управлять ими. В языке Dart для этого существуют коллекции. Коллекции предоставляют более гибкий способ работы с группами объектов. В отличие от массивов которые используются в других языках (например в С++\C#), коллекция, с которой вы работаете, может расти или уменьшаться динамически при необходимости. Некоторые коллекции допускают назначение ключа любому объекту, который добавляется в коллекцию, чтобы в дальнейшем можно было быстро извлечь связанный с ключом объект из коллекции. Так же коллекции могут быть параметризированы (generics). Dart изначально содержит API основных коллекций:

  • списков (List) ,
  • множеств (Set) ,
  • хешей (Map) .

List (список)

  • List представляет собой массив с фиксированным или динамическим размером, и с доступом к элементам, осуществляемым при помощи числового индекса. Данная коллекция по определению упорядочена, и соответственно можно полностью управлять тем, куда помещать новые элементы, откуда удалять элементы и сортировать и переупорядочивать существующие. Кроме этого списки поддерживают операции поиска элементов в коллекции и могут быть обобщенными.

Приведем несколько примеров:

// Создание списка с использованием конструктора List.
var cars = new List();

// Рекомендуемый способ - использовать литерал List:
var honda = ['Accord', 'Civic', 'CR-V'];

// Добавить в список с помощью метода add:
honda.add('NSX');

// Можно добавить сразу несколько значений:
honda.addAll(['Pilot', 'HR-V']);

// Удалим модель 'Accord' с помощью метода remove
honda.remove('Accord');

// Удалим третий элемент коллекции (будет удален 'CR-V')
honda.removeAt(2);

// Допустим у нас есть список:
var numbers = [0, -1, 2, 4, 8, 77, 29, 1005];
// Код ниже вернет нам первый элемент
print(numbers.first);  // 0
// Получим последний элемент
print(numbers.last);   // 1005
// Отобразит сколько у нас всего элементов хранится в коллекции
print(numbers.length); // 8

//Тип списка может быть параметризирован
var subaru = List();
subaru.add('Forester');
subaru.add(5); // Возникнет ошибка

Set (множество)

  • В Dart коллекция Set представляют собой неупорядоченный набор уникальных элементов. Поскольку элементы не упорядочены, нет возможности получать их по индексу (позиции). Для создания Set применяются фигурные скобки {}.

Рассмотрим несколько примеров:

// Создаем коллекцию множеств:
var sets = {0, 2, 3, 5};

// Альтернативные возможности создать коллекцию Set:
Set sets = {0, 2, 3, 5};
var sets =  {0, 2, 3, 5};
Set sets =  {0, 2, 3, 5};
var ProcessorSet = {
  'Ryzen',
  'Core',
  'Pentium',
  'Athlon',
  'Sempron',
};

// Добавляем элементы в нашу коллекцию 'cars' после её создания:
var cars = new Set();
cars.add('Toyota', 'Subaru', 'Honda');

// Удаление элемента из коллекции.
cars.remove('Honda');
  • Методы contains() и containsAll() служат для проверки существования элемента в наборе.
var cars = new Set();
cars.addAll(['Toyota', 'Subaru', 'Honda']);

// Проверка, содержится ли элемент в коллекции.
assert(cars.contains('Lexus'));

// Проверка существования элементов в коллекции.
assert(cars.containsAll(['Subaru', 'Honda']));

Map (хэш)

  • Хэш, известный как словарь (ассоциативный массив) или хэш, это неупорядоченный набор пар ключ-значение . В хеше, для облегчения поиска, значение привязывается к ключу. Для определения хешей так же необходимы фигурные скобки {}, можно использовать простой синтаксис литерала или использовать конструктор.

Посмотрим на примерах:

// Создаем хеш с ключами Samsung, Motorola, Xiaomi и их значениями:
var pda = {
  'Samsung'   : ['Note 10', 'Galaxy'],
  'Motorola'  : ['RAZR v3i', 'slv 9'],
  'Xiaomi'    : ['Mi Mix', 'Redmi 8']
};
// Альтернативно:
Map> pda = {
  'Samsung'   : ['Note 10', 'Galaxy'],
  'Motorola'  : ['RAZR v3i', 'slv 9'],
  'Xiaomi'    : ['Mi Mix', 'Redmi 8']
};
// Создание хеш-коллекции где ключ имеет тип int:
var pda_number = {
        1: "Samsung",
        2: "Nokia",
        3: "Meizu"
};
// Альтернативно этому:
Map pda_numbers = {
        1: "Samsung",
        2: "Nokia",
        3: "Meizu"
};

// Используя ключи, мы можем получить или изменить значения элементов:
var pda_numbers = {
        1: "Samsung",
        2: "Nokia",
        3: "LG"
    };
    pda_numbers[3] = "BlackBerry"; // установим значение BlackBerry вместо LG
    print(pda_numbers[3]);         // BlackBerry
}

То есть каждый элемент в Map фактически представляет собой объект Map<K, V>, где K - тип ключей, а V - тип значений. У этого типа есть два свойства: key (ключ элемента) и value (значение элемента).