18.2. Sekwencje, mapy i zbiory
Wśród różnych rodzajów kolekcji możemy wyróżnić trzy grupy: sekwencje, mapy i zbiory. Kolekcje należące do każdej z tych grup są funkcjami, a więc posiadają metodę apply, ale różnią się sposobem działania tej metody. Listy i tablice są przykładem sekwencji. Sekwencje rozszerzają cechę o nazwie Seq i zawierają uporządkowany ciąg elementów ponumerowanych począwszy od 0. Sekwencję można utworzyć za pomocą metody apply obiektu Seq.
scala> val seq = Seq(4,5,6,7) seq: Seq[Int] = List(4, 5, 6, 7)
Cecha Seq[+A] rozszerza typ PartialFunction[Int, A], zatem jest to funkcja częściowa. Metoda apply w sekwencjach ma parametr typu Int i zwraca element znajdujący się w sekwencji na określonej przez wartość tego parametru pozycji. Dla niektórych wartości parametru wartość funkcji może być niezdefiniowana.
scala> seq(0) res0: Int = 4 scala> seq(1) res1: Int = 5 scala> seq(2) res2: Int = 6 scala> seq.isDefinedAt(5) res3: Boolean = false scala> seq(5) java.lang.IndexOutOfBoundsException: 5 at scala.collection.LinearSeqOptimized$class.apply(LinearSeqOptimized.scala:65) at scala.collection.immutable.List.apply(List.scala:84) ... 33 elided
Sekwencje mogą posiadać na różnych pozycjach elementy o takiej samej wartości.
scala> val a = Seq('a,'b,'a,'c)
a: Seq[Symbol] = List('a, 'b, 'a, 'c)
scala> a(0)
res5: Symbol = 'a
scala> a(2)
res6: Symbol = 'a
scala> a(0) == a(2)
res7: Boolean = true
Innym rodzajem kolekcji są zbiory. Zbiory grupują elementy gwarantując, że żaden z nich nie powtarza się, czyli nie występuje więcej, niż jeden raz. Zbiory rozszerzają cechę o nazwie Set. Zbiór można utworzyć za pomocą metody apply obiektu Set. Jeśli na liście argumentów tej metody podamy powtarzające się wartości, to w zbiorze zostaną one umieszczone tylko raz.
scala> val set = Set('a,'b,'a,'c)
set: scala.collection.immutable.Set[Symbol] = Set('a, 'b, 'c)
Zbiory są zwykłymi funkcjami, a nie funkcjami częściowymi, a więc mają zdefiniowane wartości dla wszystkich przyjmowanych przez nie argumentów. Cecha Set[A] rozszerza funkcję (A => Boolean). Metoda apply dla zbiorów przyjmuje jako argument dowolną wartość zgodną z typem przechowywanym przez zbiór i zwraca wartość logiczną określającą, czy podana w argumencie wartość należy do zbioru.
scala> set('a)
res8: Boolean = true
scala> set('b)
res9: Boolean = true
scala> set('d)
res10: Boolean = false
Jeszcze innym rodzajem kolekcji są mapy. Mapy przechowują pary wartości. Pierwsza wartość z pary jest zwana kluczem. Klucze w mapie są unikalne, co oznacza że w danej kolekcji może być tylko jedna para wartości posiadająca konkretną wartość klucza. Na drugiej pozycji w przechowywanych przez mapę parach znajdują się wartości odpowiadające wartościom kluczy z pierwszej pozycji. Wartości nie są unikalne, co oznacza że mogą się powtarzać w ramach tej samej mapy. Mapę można utworzyć za pomocą metody apply obiektu Map.
scala> val map = Map(('a,1.0),('b,2.0))
map: scala.collection.immutable.Map[Symbol,Double] = Map('a -> 1.0, 'b -> 2.0)
Dzięki zdefiniowanej w obiekcie Predef niejawnej konwersji, przy tworzeniu map można wykorzystać operację ->, która tworzy dwuelementowe krotki.
scala> 'a->1.0
res11: (Symbol, Double) = ('a,1.0)
scala> val map2 = Map('a->1.0,'b->2.0)
map2: scala.collection.immutable.Map[Symbol,Double] = Map('a -> 1.0, 'b -> 2.0)
Cecha Map[A, +B] rozszerza typ PartialFunction[A, B]. Wartość funkcji jest niezdefiniowana dla kluczy, które nie są przechowywane w mapie. Metoda apply mapy przyjmuje jeden argument, o typie odpowiadającym typowi klucza mapy i w przypadku, gdy w mapie znajduje się element o podanej wartości klucza, metoda zwraca wartość odpowiadającą temu kluczowi.
scala> map('a)
res12: Double = 1.0
scala> map('b)
res13: Double = 2.0
W przeciwnym przypadku metoda generuje wyjątek.
scala> map.isDefinedAt('d)
res14: Boolean = false
scala> map('d)
java.util.NoSuchElementException: key not found: 'd
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.MapLike$class.apply(MapLike.scala:141)
at scala.collection.AbstractMap.apply(Map.scala:59)
... 33 elided
![]() | Analogiczne działanie do metody ->, ma metoda →. |

