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

04.06.2020
Статья написана для старой версии Flutter и сейчас обновляется. Часть кода может не компилироваться на актуальной версии.

Во многих приложениях требуется создавать группы связанных объектов и управлять ими. В языке 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 (значение элемента).