Collections

Создание коллекций с нуля

Language

У вас есть синтаксис List(1, 2, 3) для создания списка из трех целых чисел и Map('A' -> 1, 'C' -> 2) для создания мапы с двумя элементами. На самом деле, это универсальная функциональность коллекций Scala. Можно получить любую коллекцию написав ее название и указав следом список элементов в круглых скобках. В результате получится новая коллекция с заданными элементами. Вот еще несколько примеров:

Iterable()                // Пустая коллекция
List()                    // Пустой список
List(1.0, 2.0)            // Список с элементами 1.0, 2.0
Vector(1.0, 2.0)          // Вектор с элементами 1.0, 2.0
Iterator(1, 2, 3)         // Итератор возвращающий три целых числа.
Set(dog, cat, bird)       // Множество с тремя объектами
HashSet(dog, cat, bird)   // Хэш-множество с темиже объектами
Map('a' -> 7, 'b' -> 0)   // Мапа с привязкой цифр к буквам

Каждая из вышеперечисленных строк это вызов метода apply какого-то объекта. Например, третья строка выше разворачивается следующим образом

List.apply(1.0, 2.0)

Так что это вызов метода apply объекта-компаньона класса List. Этот метод берет произвольное количество аргументов и строит из них список. Каждый класс коллекций библиотеки Scala имеет объект-компаньон с таким apply методом. Не имеет значения, является ли класс конкретной реализацией коллекции, такой как List, LazyList, Vector, или это абстрактный базовый класс, такой как Seq, Set или Iterable. В последнем случае вызов apply приведет к некой реализации по умолчанию для базового абстрактного класса. Примеры:

scala> List(1, 2, 3)
res17: List[Int] = List(1, 2, 3)
scala> Iterable(1, 2, 3)
res18: Iterable[Int] = List(1, 2, 3)
scala> mutable.Iterable(1, 2, 3)
res19: scala.collection.mutable.Iterable[Int] = ArrayBuffer(1, 2, 3)

Помимо apply, каждый объект-компаньон коллекции еще определяет элемент empty, который возвращает пустую коллекцию. Так что вместо List() можно написать List.empty, вместо Map(), Map.empty и так далее.

Операции, предоставляемые объектом-компаньоном коллекции, обобщены в следующей таблице. Короче говоря.

  • concat, которая объединяет произвольное количество коллекций,
  • fill и tabulate, которые генерируют одно- или многомерные коллекции заданных размеров, инициализированные некоторой табулируемой функцией или выражением,
  • range, которая генерирует целочисленные коллекции с постоянной длиной шага,
  • iterate и unfold, который генерирует коллекцию в результате многократного применения функции к начальному элементу или состоянию.

Производящие методы для последовательностей

ПРИМЕР ЧТО ДЕЛАЕТ
C.empty Пустая коллекция.
C(x, y, z) Коллекция состоящая из элементов x, y, z.
C.concat(xs, ys, zs) Коллекция, полученная путем объединения элементов xs, ys, zs.
C.fill(n){e} Коллекция длины n, где каждый элемент вычисляется выражением e.
C.fill(m, n){e} Коллекция коллекций размерности m×n, где каждый элемент вычисляется выражением e. (существует и в более высоких измерениях).
C.tabulate(n){f} Коллекция длины n, где элемент каждого индекса i вычисляется с помощью f(i).
C.tabulate(m, n){f} Коллекция коллекций измерений m×n, где элемент каждого индекса (i, j) вычисляется с помощью f(i, j). (существует также в более высоких измерениях).
C.range(start, end) Коллекция из целых чисел от start до end-1.
C.range(start, end, step) Коллекция целых чисел, начиная со start и продвигаясь на шаг step увеличиваясь до конечного значения end (не включая его самого) .
C.iterate(x, n)(f) Коллекция длины n с элементами x, f(x), f(f(x)), …
C.unfold(init)(f) Коллекция, использующая функцию f для вычисления следующего элемента и состояния, начиная с начального состояния init.

Contributors to this page: