Hintergründe

Einstieg
Paketstruktur
Typunterscheidung
High-Level Abstraktionen
High-Level Abstraktionen sequenzieller Collections
Standard Collections
Links

Einstieg

Scala bringt eine große Anzahl von Collection-Klassen in der Standarddistribution mit sich. Die Version 2.9 von Scala brachte erstmals spezielle Collection Klassen mit, welche für die Parallelverarbeitung vorgesehen sind. Diese Collections können z.B. direkt, ohne das der Programmierer eingreifen muss, auf mehreren Rechenkernen verarbeitet werden.

Grundsätzlich können wir die Scala Collection Klassen in folgende Kategorien einteilen:

  • Unveränderliche Collections zur sequenziellen Verarbeitung

  • Veränderliche Collections zur sequenziellen Verarbeitung

  • Unveränderliche Collections für Parallelverarbeitung

  • Veränderliche Collections für Parallelverarbeitung

Paketstruktur

Die unterschiedlichen Kategorien der Collections lassen sich auch der Paketstruktur entnehmen, in der die Scala Collections definiert sind. Diese sind:

scala.collection

Das Package scala.collection bildet die Basis für alle Collections in den Scala Standardbibliotheken (veränderlich, unveränderlich, sequenziell und parallel). Collections aus diesem Package können veränderlich und unveränderlich sein. Die enthaltenen Collections verändern nicht sich selbst, können jedoch evtl. von außen verändert werden.

scala.collection.generic

scala.collection.generic enthält Collection-Templates für gemeinsame Operationen verschiedener Collection Typen. Der Anwender der Scala Collections wird in der Regel dieses Package in der Regel nicht verwenden.

scala.collection.immutable

Im Package scala.collection.immutable befinden sich die unveränderlichen, sequenziellen Scala Collections. Nach der Erzeugung einer Collection lässt diese sich nicht wieder verändern. Jede Operation, die den Anschein einer Veränderung weckt, führt zu einer neuen Collection auf Basis der Collection, auf der die Operation aufgerufen wurde. Sequenzielle, unveränderliche Collections lassen sich mithilfe der Funktion par in parallele, unveränderliche Collections umwandeln.

scala.collection.interface

Im Package scala.collection.interface werden Traits für die verschiedenen Collection Typen defiiert.

scala.collection.mutable

scala.collection.mutable ist das Package für die veränderlichen, sequenziellen Collections. Hier ist jedoch darauf zu achten, dass nicht alle Methoden (Funktionen) entsprechender Collection zu einer Veränderung der jeweiligen Collection führt. Einige Methoden erzeugen, wie bei den unveränderlichen Collections, neue Collections auf Basis der Collection auf der die Methode aufgerufen wurde. Andere Methoden führen hingegen zur Veränderung der ursprünglichen Collection. Hilfe bei der Unterscheidung kann die Scala-API liefern. Sequenzielle, veränderliche Collections lassen sich mithilfe der Funktion par in parallele, veränderliche Collections umwandeln.

scala.collection.parallel.immutable

Wie der Name schon sagt, enthält das Package scala.collection.parallel.immutable die Elemente der unveränderlichen, parallelen Collections in Scala. Unveränderliche, parallele Collections können mithilfe der Funktion seq in sequenzielle, unveränderliche Collections umgewandelt werden.

scala.collection.parallel.mutable

Auch hier ist der Name Programm. Das Package scala.collection.paralell.mutable enthält die Elemente der veränderlichen, parallelen Collections. Wie auch bei den sequenziellen, veränderlichen Collections, führt ein Aufruf einer Funktion auf die Collection nicht unbedingt zu einer Veränderung der Collection. Vielfach erzeugen werden die Funktionen gemeinsam mit den unveränderlichen Collections verwendet und erzeugen neue Collections auf deren Basis. Mithilfe der Funktion seq kann aus einer parallelen, veränderlichen Collection eine sequenzielle, veränderliche Collection erzeugen.

scala.collection.parallel

Im Package scala.collection.parallel sind die Basiselemente (im Wesentlichen Traits und Objects) für die parallelen Collections definiert. Sie bilden die Basis für veränderliche und unveränderliche parallele Collections in Scala.

scala.collection.script

Im Package scala.collection.script sind weitere Bestandteile der Scala Collections definiert, welche in der Regel vom Anwender nicht verwendet werden.

Typunterscheidung

Es gibt eine Vielzahl unterschiedlicher Collections, die jeweils Vor- und Nachteile in ihrer Anwendung haben. Die nachfolgende Auflistung zeigt einige Typen von Collections, die auch in Scala Verwendung finden.

  • List

    Eine List ist eine geordnete Menge von gleichartigen Typen. Häufig werden List Datenstrukturen als Linked-List implementiert, bei denen die Elemente nicht an einem fest definierten Platz im Speicher gehalten werden. Jedes Element einer List kennt dabei das nachfolgende Element in der Liste. Auf die einzelnen Elemente einer List kann über Ihren Index zugegriffen werden.

  • Stream

    Ein Stream ist eine Datenstruktur ähnlich der List. Die Bestimmung des Elementinhaltes erfolgt jedoch erst beim ersten Zugriff auf das Element.

  • Queue

    Eine Queue ist eine Datenstruktur, die ein Menge von Elementen enthält, die nach dem First In First Out (FIFO) Prinzip verarbeitet werden.

  • Seq

    Eine Seq ist eine geordnete Datenstruktur gleichartiger Elemente. Auf die Elemente einer Seq kann über Ihren Index zugegriffen werden.

  • Stack

    Ein Stack ist eine Datenstruktur, die nach dem Last In First Out (LIFO) Prinzip arbeitet, d.h. das zuletzt hinzugefügte Element wird als Erstes entnommen.

  • Set

    Ein Set ist eine Datenstruktur ähnlich der List. Der Hauptunterschied liegt darin, dass ein Set keine doppelten Elemente enthält.

  • Map

    Eine Map enthält Schlüssel - Werte Paare. Die Schlüssel sind eindeutig. Werte können mehrfach enthalten sein.

  • Range

    Ein Range ist eine Menge von Int Werten. Die Int Werte sind dabei von einem Startwert bis zu einem Endwert in einer festen Schrittweite (nicht null aber evtl. Negativ) geordnet.

  • Vector

    Ein Vector ist eine geordnete Datenstruktur, auf deren Elemente über Ihren Index zugegriffen werden kann. Ein Vector ist auf die Verarbeitung der Elemente am Anfang des Vector optimiert.

High-Level Abstraktionen

Das Package scala.collection definiert die "High-Level" Abstraktionen der Scala Collections. Sie bieten die Basis für veränderliche (engl. mutable), unveränderliche (eng. immutable) sowie für die parallelen (veränderliche und unveränderliche) Collections.

Nachfolgend ein Diagramm zur allgemeinen Collection Hierarchie1.

Allgemeine Collection Hierachie

Wie dem Bild zu entnehmen ist, sind die High-Level Abstraktionen in drei Bereiche unterteilt. Der mittlere Bereich mit GenTraversable, GenIterable und GenSeq bilden die Basis für alle Collections. Im linken Bereich sind mit Traversable, Iterable und Seq die High-Level Abstraktionen der sequenziellen Collections zu finden. Mit ParIterable und ParSeq sind die entsprechenden Abstraktionen der parallel Collections auf der rechten Seite zu finden.

Auch wenn es Vielen klar ist, möchte ich hier kurz auf die parallel Collections eingehen. Wie der Name es vermuten lässt, sind parallele Collections für parallele (nebenläufige) Verarbeitung gedacht. Die Parallelität wird dabei beim Aufruf von Methoden wir foreach automatisch erzeugt. Dabei werden die im Rechner vorhandenen Kerne (Hyperthreads) automatisch ausgenutzt. Mithilfe von parallel Collections können wir somit auf einfache Weise die im Rechner vorhandenen Kerne ausnutzen. Zum Anfang braucht man sich auch keine Gedanken zu machen, ob wir sequenzielle oder parallele Collections einsetzen. Für jede Collection gibt es die Methode par um aus einer sequenziellen Collection eine parallel Collection zu machen und die Methode seq um aus einer parallelen Collection eine sequenzielle Collection zu machen.

High-Level Abstraktionen sequenzieller Collections


Die High-Level Abstraktionen sequenzieller Collections befinden sich im Package scala.collection. Das nachfolgende Diagramm zeigt den Aufbau der High-Level Abstraktionen sequenzieller Collections in Scala.

High-Level Abstraktionen

Standard Collections

Importieren wir keine Collection Klassen bzw. Packages und geben keinen voll qualifizierenden Namen an verwenden wir in Scala standardmäßig unveränderliche Collections. Dass wir diese Collections nicht importieren müssen, ist keine Besonderheit des entsprechenden Packages, sondern liegt daran, dass in Scala Typen definiert sind (welche automatisch importiert werden), die auf die entsprechenden unveränderlichen Collections zeigen. Beispiele für derartige Collection Klassen sind List, Range, Stream, ... .

Martin Odersky, Lex Spoon
The Architecture of Scala Collections
http://www.scala-lang.org/docu/files/collections-api/collections-impl.html# Flagge Großbritanien


Martin Odersky, Lex Spoon
The Scala 2.8 Collection API Flagge Großbritanien
http://lampwww.epfl.ch/~odersky/whatsnew/collections-api/collections.html Flagge Großbritanien


Community-driven documentation for Scala Flagge Großbritanien
Performance Characteristics Flagge Großbritanien
http://docs.scala-lang.org/overviews/collections/performance-characteristics.html


Heiko Seeberger
Scala 2.8 - Die wichtigsten Neuerungen
Teil 2: Scala 2.8: Die überarbeitete Collection Library