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 .

Język programowania Scala Wydanie 2. Copyright © Grzegorz Balcerek 2016

Licencja Creative Commons

Ten utwór jest dostępny na licencji Creative Commons Uznanie autorstwa-Na tych samych warunkach 4.0 Międzynarodowe.

Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.