Collections

Введение

Language

Martin Odersky и Lex Spoon

Популярно мнение, что новые коллекции это самое значимое изменение в Scala версии 2.8. В Scala и раньше были коллекции (и на самом деле, новая модель во многом совместима с прежней). Но только начиная с версии 2.8 появилась единая, общая и всеобъемлющая база для всех типов коллекций.

Несмотря на то, что улучшения коллекций на первый взгляд едва заметны, они могут привести к существенному изменению в вашем стиле программирования.
Теперь чаще, при работе на высоком уровне, вся коллекция становится базовым строительным блоком вашей программы, а не её отдельные элементы.

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

Простота: Небольшого набора из 20-50 методов достаточно для решения большинства задач. Нет необходимости использовать запутанные циклы или рекурсии. Персистентные коллекции и операции без побочных эффектов означают, что вам не нужно беспокоиться о случайном повреждении существующих коллекций новыми данными. Больше нет путаницы из-за использования итераторов и одновременного изменения коллекций.

Лаконичность: Одной командой можно достичь, столько же, сколько обычно получают используя несколько вложенных операций с циклами. Вы можете выразить функциональные операции с помощью простого синтаксиса и с легкостью сочетать операции, создавая ощущение работы со специализированным под задачу языком.

Безопасность: Требуется определенный опыт, чтоб погрузится в эту специфику. Статически типизированная и функциональная природа коллекций Scala подразумевает, что подавляющее большинство ошибок, которые вы можете совершить, будут пойманы во время компиляции. Это потому что:

  1. Коллекции сами по себе очень активно используются, поэтому хорошо протестированы.
  2. Использование операции в коллекциях создает явное описание того, что мы ожидаем для входящих данных и для результата.
  3. Это явное описание для входа и результата подвергается статической проверке типа. В результате подавляющее большинство проблем будет проявляться в виде ошибок типов. Поэтому запуск программ из нескольких сотен строк, с первого раза, вполне типичная ситуация.

Скорость: Все операции в коллекциях уже настроены и оптимизированы. В результате, работа коллекций получается очень эффективной. Можно конечно сделать немного более эффективную настройку структур данных и операций с ними, но при этом, вероятно, вы получите хуже эффективность в непосредственной реализации и использовании. Кроме того, коллекции оптимизированы для параллельного исполнения на нескольких ядрах. Параллельные коллекции поддерживают те же операции, что и последовательные, поэтому нет необходимости в изучении новых операций или переписывании кода. Вы можете превратить последовательную коллекцию в параллельную просто вызвав метод par.

Универсальность: Коллекции обеспечивают одинаковые операции на любом типе коллекций, где это имеет смысл. Таким образом, можно достичь многого, имея сравнительно небольшой набор операций. Например строка, в принципе, представляет собой последовательность символов. Следовательно, в коллекциях Scala строки поддерживают все операции которые есть у последовательностей (Seq). То же самое относится и к массивам.

Пример: Вот лишь одна строчка кода, демонстрирующая преимущества Scala коллекций.

val (minors, adults) = people partition (_.age < 18)

Сразу становится понятно, что делает эта строчка: она разделяет коллекцию людей people на несовершеннолетних minors и взрослых adults в зависимости от возраста age. Поскольку метод partition определен в базовом типе коллекции TraversableLike, этот код работает для любого типа коллекций, включая массивы. Полученные в результате коллекции minors и adults будут иметь тот же тип, что и коллекция people .

Этот код намного лаконичнее, чем несколько циклов, необходимых для того, чтоб провести обработку традиционным методом (три цикла для массива, т.к. промежуточные результаты должны быть сохранены где-то в другом месте).
Как только вы освоите базовую схему работы с коллекциями, вы оцените на сколько проще и безопаснее написание такого кода, в отличии от более низкоуровневого кода с циклами.
Кроме того, сама операция partition работает довольно быстро и будет работать еще быстрее на многоядерных процессорах при использовании параллельных коллекций. (Параллельные коллекции стали частью Scala начиная с версии 2.9.)

В этом разделе подробно рассматриваются API классов коллекций Scala с пользовательской точки зрения.
Вы также познакомитесь со всеми фундаментальными классами и методами, которые есть у коллекций.

Contributors to this page: