Scala предоставляет прекрасный набор коллекций. Также доступно некоторое количество абстракций для типов коллекций. Это позволяет вам писать код, который может работать с коллекцией Foo
без необходимости беспокоиться о том является коллекция List
, Set
, или чем-то еще.
Эта страница предлагает отличный способ следить за стандартными реализациями и ссылками на все документы scaladoc.
Стандартный связанный список.
scala> List(1, 2, 3) res0: List[Int] = List(1, 2, 3)
Вы можете создать его используя функциональный стиль.
scala> 1 :: 2 :: 3 :: Nil res1: List[Int] = List(1, 2, 3)
Смотрите также: API документация
Множество, не содержащее одинаковых элементов
scala> Set(1, 1, 2) res2: scala.collection.immutable.Set[Int] = Set(1, 2)
Смотрите также: API документация
Последовательности, имеющие определенный порядок
scala> Seq(1, 1, 2) res3: Seq[Int] = List(1, 1, 2)
(Заметьте, что возвращается список. Seq
– это трейт; List – это отличная реализация Seq. Существует фабричный объект Seq
, который, как вы здесь увидите, создает списки.)
Смотрите также: API документация
Map – это хранилище ключ-значение.
scala> Map('a' -> 1, 'b' -> 2) res4: scala.collection.immutable.Map[Char,Int] = Map((a,1), (b,2))
Смотрите также: API документация
Все представляет собой трейты, расположенные в mutable и immutable пакетах, имеющие либо обычную реализацию, либо специальную.
Все коллекции имеют возможность обхода. Этот трейт определят стандарт функциональных комбинаторов. Эти комбинаторы написаны используя foreach
, и который коллекции могут реализовать.
Смотрите также: API документация
Имеющийся метод iterator()
позволяет вам итерировать элементы.
Смотрите также: API документация
Последовательность упорядоченных элементов.
Смотрите также: API документация
Коллекция не повторяющихся элементов.
Смотрите также: API документация
Коллекция пар ключ-значение.
Смотрите также: API документация
Все методы, показанные ниже, доступны для обхода. Аргументы и возвращаемые типы не всегда будет выглядеть так, потому что подклассы могут быть свободно переопределены.
def head : A def tail : Traversable[A]
Вот где определены функциональные комбинаторы.
def map [B] (f: (A) => B) : CC[B]
возвращается коллекция, где каждый элемент преобразован с помощью f
def foreach[U](f: Elem => U): Unit
изменяется коллекция, при выполнении f
над каждым элементом.
def find (p: (A) => Boolean) : Option[A]
возвращает первый элемент, который удовлетворяет функции предикату
def filter (p: (A) => Boolean) : Traversable[A]
возвращает коллекцию со всеми элементами, удовлетворяющих функции-предикату
Разбивка:
def partition (p: (A) ⇒ Boolean) : (Traversable[A], Traversable[A])
Разделяет коллекцию на две половины, основываясь на результате функции-предиката
def groupBy [K] (f: (A) => K) : Map[K, Traversable[A]]
Преобразование:
Вы можете конвертировать коллекцию одного типа в другой.
def toArray : Array[A] def toArray [B >: A] (implicit arg0: ClassManifest[B]) : Array[B] def toBuffer [B >: A] : Buffer[B] def toIndexedSeq [B >: A] : IndexedSeq[B] def toIterable : Iterable[A] def toIterator : Iterator[A] def toList : List[A] def toMap [T, U] (implicit ev: <:<[A, (T, U)]) : Map[T, U] def toSeq : Seq[A] def toSet [B >: A] : Set[B] def toStream : Stream[A] def toString () : String def toTraversable : Traversable[A]
Давайте сконвертируем Map в Array. Вы получите Array, содержащий пары ключ-значение.
scala> Map(1 -> 2).toArray res41: Array[(Int, Int)] = Array((1,2))
Добавляет возможность итерирования.
def iterator: Iterator[A]
Что может дать вам итератор?
def hasNext(): Boolean def next(): A
Похоже на Java. Вы не будет часто видеть итераторы в программе на Scala, у вас больше шансов увидеть функциональные комбинаторы или расширенный for.
def contains(key: A): Boolean def +(elem: A): Set[A] def -(elem: A): Set[A]
Последовательность пар ключ-значение с поиском по ключу.
Передайте список пар внутрь apply(), например так
scala> Map("a" -> 1, "b" -> 2) res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,1), (b,2))
Или так:
scala> Map(("a", 2), ("b", 2)) res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,2), (b,2))
Что это за знак ->
? Это не какой-то специальный синтаксис, это метод, который возвращает кортеж.
scala> "a" -> 2 res0: (java.lang.String, Int) = (a,2)
Помните, что это всего лишь синтаксический сахар для
scala> "a".->(2) res1: (java.lang.String, Int) = (a,2)
Вы можете также использовать знак ++
для создания объектов
scala> Map.empty ++ List(("a", 1), ("b", 2), ("c", 3)) res0: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,1), (b,2), (c,3))
HashSet и HashMap Взгляните, самые часто используемые формы этих коллекций. HashSet API, HashMap API
TreeMap – это подкласс SortedMap, дает вам упорядоченный доступ к элементам. TreeMap API
Vector Быстрая случайная выборка и быстрое обновление. Vector API
scala> IndexedSeq(1, 2, 3) res0: IndexedSeq[Int] = Vector(1, 2, 3)
Range Упорядоченная последовательность целых чисел, отделенных определенным интервалом. Вы будете часто видеть их там, где до этого использовались циклы. Range API
scala> for (i <- 1 to 3) { println(i) } 1 2 3
Range имеет стандартные функциональные комбинаторы.
scala> (1 to 3).map { i => i } res0: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3)
Используя методы apply в трейтах, вы получаете экземпляр стандартной реализации. Например, Iterable(1, 2) возвратит List как стандартную реализацию метода apply.
scala> Iterable(1, 2) res0: Iterable[Int] = List(1, 2)
То же самое с Seq
scala> Seq(1, 2) res3: Seq[Int] = List(1, 2) scala> Iterable(1, 2) res1: Iterable[Int] = List(1, 2) scala> Sequence(1, 2) warning: there were deprecation warnings; re-run with -deprecation for details res2: Seq[Int] = List(1, 2)
Set
scala> Set(1, 2) res31: scala.collection.immutable.Set[Int] = Set(1, 2)
IndexedSeq быстрый случайный доступ к элементам и быстрая операция определения длины length. API документация
LinearSeq быстрый доступ к первому элементу при доступе к голове последовательности, а также быстрые операции с хвостом. API документация
immutable
За
Против
Scala позволяет нам быть прагматичными, она призывает к неизменности значений, но не наказывает нас, если мы нуждаемся в изменчивости. Это очень похоже на var против val. Мы всегда начинаем с val и обращаемся к var, когда это требуется.
Мы начинаем с immutable версий коллекций, но переходим на mutable, если нужно. Использование immutable коллекций означает, что вы случайно не измените состояние в нескольких потоках.
Все классы, которые мы обсуждали выше были immutable. Давайте обсудим часто используемые mutable коллекции.
HashMap определяет getOrElseUpdate
, +=
HashMap API
scala> val numbers = collection.mutable.Map(1 -> 2) numbers: scala.collection.mutable.Map[Int,Int] = Map((1,2)) scala> numbers.get(1) res0: Option[Int] = Some(2) scala> numbers.getOrElseUpdate(2, 3) res54: Int = 3 scala> numbers res55: scala.collection.mutable.Map[Int,Int] = Map((2,3), (1,2)) scala> numbers += (4 -> 1) res56: numbers.type = Map((2,3), (4,1), (1,2))
ListBuffer и ArrayBuffer определяет +=
ListBuffer API, ArrayBuffer API
LinkedList и DoubleLinkedList LinkedList API, DoubleLinkedList API
PriorityQueue API документация
Stack и ArrayStack Stack API, ArrayStack API
StringBuilder Interestingly, StringBuilder is a collection. API документация
Вы можете просто перемещаться между Java и Scala коллекциями, используя набор неявных преобразований, которые доступны в пакете JavaConversions.
import scala.collection.JavaConversions._ val sl = new scala.collection.mutable.ListBuffer[Int] val jl : java.util.List[Int] = sl val sl2 : scala.collection.mutable.Buffer[Int] = jl assert(sl eq sl2)
Двусторонние преобразования:
scala.collection.Iterable <=> java.lang.Iterable scala.collection.Iterable <=> java.util.Collection scala.collection.Iterator <=> java.util.{ Iterator, Enumeration } scala.collection.mutable.Buffer <=> java.util.List scala.collection.mutable.Set <=> java.util.Set scala.collection.mutable.Map <=> java.util.{ Map, Dictionary } scala.collection.mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap
Дополнительно, имеется набор односторонних преобразований:
scala.collection.Seq => java.util.List scala.collection.mutable.Seq => java.util.List scala.collection.Set => java.util.Set scala.collection.Map => java.util.Map