Kurz: Scala hat eine reiche, standardmäßig unveränderliche Collection-Bibliothek: List, Vector, Set, Map, Seq, Array. Operationen liefern neue Collections.
Teil des Kurses Scala
Collections
Scala hat eine reiche, standardmäßig unveränderliche Collection-Bibliothek: List, Vector, Set, Map, Seq, Array. Operationen liefern neue Collections.
@main def main(): Unit =
val z = List(5, 3, 9, 1, 7)
println(s"${z.head} ${z.tail} ${z.last} ${z.length} ${z(2)} ${z.take(2)} ${z.drop(3)}")
println(s"${0 :: z} ${z :+ 100} ${z ++ List(8)} ${z.reverse} ${z.sorted} ${z.sortBy(-_)} ${z.sortWith(_ > _)}")
println(s"${z.map(_ * 2)} ${z.filter(_ > 4)} ${z.sum} ${z.product} ${z.min} ${z.max} ${z.size}")
println(s"${z.exists(_ > 8)} ${z.forall(_ > 0)} ${z.count(_ % 2 == 1)} ${z.find(_ > 5)} ${z.indexOf(9)} ${z.contains(3)}")
println(s"${z.foldLeft(0)(_ + _)} ${z.reduce(_ max _)} ${z.partition(_ > 4)} ${z.zip("abcde")} ${z.sliding(2).toList}")
println(s"${z.grouped(2).toList} ${z.takeWhile(_ > 2)} ${z.dropWhile(_ > 2)} ${z.span(_ > 2)} ${z.splitAt(2)}")
println(s"${List(List(1, 2), List(3)).flatten} ${List("ab", "cd").flatMap(_.toList)} ${z.distinct} ${z.mkString(", ")} ${z.mkString("[", ";", "]")}")
println(s"${List(1, 2, 2, 3, 3, 3).groupBy(identity).view.mapValues(_.size).toMap.toList.sorted}")
println(s"${List("a", "bb", "ccc").map(_.length)} ${(1 to 5).toList.scanLeft(0)(_ + _)} ${List.fill(3)("x")} ${List.range(0, 10, 3)} ${List.tabulate(4)(i => i * i)}")
println(s"${z.zipWithIndex} ${z.lift(10)} ${z.lift(1)} ${z.collect { case x if x > 4 => x * 10 }} ${z.maxBy(x => (x - 5).abs)}")Ausgabe:
5 List(3, 9, 1, 7) 7 5 9 List(5, 3) List(1, 7)
List(0, 5, 3, 9, 1, 7) List(5, 3, 9, 1, 7, 100) List(5, 3, 9, 1, 7, 8) List(7, 1, 9, 3, 5) List(1, 3, 5, 7, 9) List(9, 7, 5, 3, 1) List(9, 7, 5, 3, 1)
List(10, 6, 18, 2, 14) List(5, 9, 7) 25 945 1 9 5
true true 5 Some(9) 2 true
25 9 (List(5, 9, 7),List(3, 1)) List((5,a), (3,b), (9,c), (1,d), (7,e)) List(List(5, 3), List(3, 9), List(9, 1), List(1, 7))
List(List(5, 3), List(9, 1), List(7)) List(5, 3, 9) List(1, 7) (List(5, 3, 9),List(1, 7)) (List(5, 3),List(9, 1, 7))
List(1, 2, 3) List(a, b, c, d) List(5, 3, 9, 1, 7) 5, 3, 9, 1, 7 [5;3;9;1;7]
List((1,1), (2,2), (3,3))
List(1, 2, 3) List(0, 1, 3, 6, 10, 15) List(x, x, x) List(0, 3, 6, 9) List(0, 1, 4, 9)
List((5,0), (3,1), (9,2), (1,3), (7,4)) None Some(3) List(50, 90, 70) 9Maps und Sets
@main def main(): Unit =
val alter = Map("Mia" -> 17, "Tom" -> 25)
val mehr = alter + ("Zoe" -> 31)
val ohne = mehr - "Tom"
println(s"${alter("Mia")} ${alter.get("Ben")} ${alter.getOrElse("Ben", 0)} ${mehr.size} ${ohne.keys.toList.sorted}")
println(mehr.toList.sortBy(_._1))
println(mehr.map((k, v) => (k.toUpperCase, v + 1)).toList.sorted)
println(mehr.filter((_, v) => v > 20).keys.toList.sorted)
println(mehr.values.sum)
for (name, a) <- mehr.toList.sortBy(_._1) do println(s"$name => $a")
val zaehler = "mississippi".groupBy(identity).map((c, s) => c -> s.length)
println(zaehler.toList.sorted)
val wort = "ein kleiner langer Satz mit drei".split(" ").toList
println(wort.groupBy(_.length).toList.sortBy(_._1))
val s = Set(3, 1, 2, 3, 1)
println(s"${s.size} ${s.contains(2)} ${(s + 9).toList.sorted} ${(s & Set(1, 9)).toList} ${(s | Set(7)).toList.sorted} ${(s -- Set(1)).toList.sorted}")
import scala.collection.mutable
val veraenderlich = mutable.Map("a" -> 1)
veraenderlich("b") = 2
veraenderlich += ("c" -> 3)
val puffer = mutable.ArrayBuffer(1, 2)
puffer += 3
puffer.prepend(0)
println(s"${veraenderlich.toList.sorted} ${puffer}")Ausgabe:
17 None 0 3 List(Mia, Zoe)
List((Mia,17), (Tom,25), (Zoe,31))
List((MIA,18), (TOM,26), (ZOE,32))
List(Tom, Zoe)
73
Mia => 17
Tom => 25
Zoe => 31
List((i,4), (m,1), (p,2), (s,4))
List((3,List(ein, mit)), (4,List(Satz, drei)), (6,List(langer)), (7,List(kleiner)))
3 true List(1, 2, 3, 9) List(1) List(1, 2, 3, 7) List(2, 3)
List((a,1), (b,2), (c,3)) ArrayBuffer(0, 1, 2, 3)Pattern Matching
match zerlegt Werte nach Struktur. Das ist eines der Kernmerkmale von Scala:
case class Punkt(x: Int, y: Int)
def beschreibe(wert: Any): String = wert match
case 0 => "null"
case n: Int if n < 0 => s"negative Zahl $n"
case n: Int => s"Zahl $n"
case s: String if s.isEmpty => "leerer Text"
case s: String => s"Text mit ${s.length} Zeichen"
case Punkt(0, 0) => "Ursprung"
case Punkt(x, 0) => s"auf der x-Achse bei $x"
case Punkt(x, y) => s"Punkt $x/$y"
case List() => "leere Liste"
case List(a) => s"Liste mit einem Element $a"
case List(a, b, _*) => s"Liste beginnt mit $a, $b"
case (a, b) => s"Tupel $a, $b"
case Some(x) => s"Some($x)"
case None => "None"
case _ => "unbekannt"
def summe(l: List[Int]): Int = l match
case Nil => 0
case kopf :: rest => kopf + summe(rest)
@main def main(): Unit =
val tests: List[Any] = List(0, -5, 42, "", "Scala", Punkt(0, 0), Punkt(3, 0), Punkt(1, 2), List(), List(7), List(1, 2, 3), (1, "x"), Some(5), None, 3.5)
tests.foreach(t => println(beschreibe(t)))
println(summe(List(1, 2, 3, 4)))
val (a, b) = (1, 2)
val Punkt(px, py) = Punkt(5, 6)
val erstes :: zweites :: _ = List(10, 20, 30): @unchecked
println(s"$a $b $px $py $erstes $zweites")
val ergebnis = List(1, 2, 3, 4, 5, 6).collect:
case n if n % 2 == 0 => n * n
println(ergebnis)Ausgabe:
null
negative Zahl -5
Zahl 42
leerer Text
Text mit 5 Zeichen
Ursprung
auf der x-Achse bei 3
Punkt 1/2
leere Liste
Liste mit einem Element 7
Liste beginnt mit 1, 2
Tupel 1, x
Some(5)
None
unbekannt
10
1 2 5 6 10 20
List(4, 16, 36)Merke
- Collections sind unveränderlich:
List,Vector,Set,Map; veränderlich inscala.collection.mutable - Mächtige Operationen:
map,filter,foldLeft,groupBy,zip,sliding,flatMap matchmit Mustern: Werte, Typen,case class, Listen, Tupel, Guards (if)- Pattern Matching zerlegt auch in
val-Definitionen
Übungsaufgabe
Zähle mit groupBy die Wörter eines Satzes und gib die häufigsten aus.
Quiz zur Selbstkontrolle
Was liefert List(1, 2) :+ 3?
- Eine neue Liste List(1, 2, 3) (richtig)
- Die ursprüngliche Liste verändert
- 6
- Einen Fehler
Was ist ein Guard in einem Pattern?
- Eine zusätzliche if-Bedingung nach dem Muster (richtig)
- Ein Sicherheitsmerkmal
- Ein Dateischutz
- Ein Typ
Sind Scala-Standardcollections veränderlich?
- Nein, standardmäßig unveränderlich (richtig)
- Ja
- Nur Listen
- Nur Maps
Weiter im Kurs
Zurück: Typen, Kontrollfluss und Funktionen
Weiter: Klassen, Traits und Case Classes
Alle Kapitel: Scala im Überblick