Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort zur 5. Auflage
1 Allgemeine Einführung in .NET
2 Grundlagen der Sprache C#
3 Klassendesign
4 Vererbung, Polymorphie und Interfaces
5 Delegates und Ereignisse
6 Weitere .NET-Datentypen
7 Weitere Möglichkeiten von C#
8 Auflistungsklassen (Collections)
9 Fehlerbehandlung und Debugging
10 LINQ to Objects
11 Multithreading und die Task Parallel Library (TPL)
12 Arbeiten mit Dateien und Streams
13 Binäre Serialisierung
14 Einige wichtige .NET-Klassen
15 Projektmanagement und Visual Studio 2010
16 XML
17 WPF – Die Grundlagen
18 WPF-Containerelemente
19 WPF-Steuerelemente
20 Konzepte der WPF
21 Datenbindung
22 2D-Grafik
23 ADO.NET – verbindungsorientierte Objekte
24 ADO.NET – Das Command-Objekt
25 ADO.NET – Der SqlDataAdapter
26 ADO.NET – Daten im lokalen Speicher
27 ADO.NET – Aktualisieren der Datenbank
28 Stark typisierte DataSets
29 LINQ to SQL
30 Weitergabe von Anwendungen
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
Visual C# 2010 von Andreas Kühnel
Das umfassende Handbuch
Buch: Visual C# 2010

Visual C# 2010
geb., mit DVD
1295 S., 49,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1552-7
Pfeil 8 Auflistungsklassen (Collections)
Pfeil 8.1 Die Listen des Namespace »System.Collections«
Pfeil 8.1.1 Die elementaren Schnittstellen der Auflistungsklassen
Pfeil 8.2 Die Klasse »ArrayList«
Pfeil 8.2.1 Einträge hinzufügen
Pfeil 8.2.2 Datenaustausch zwischen einem Array und einer ArrayList
Pfeil 8.2.3 Die Elemente einer ArrayList sortieren
Pfeil 8.2.4 Sortieren von Arrays mit »ArrayList.Adapter«
Pfeil 8.3 Die Klasse »Hashtable«
Pfeil 8.3.1 Methoden und Eigenschaften der Schnittstelle »IDictionary«
Pfeil 8.3.2 Beispielprogramm zur Klasse »Hashtable«
Pfeil 8.4 Die Klassen »Queue« und »Stack«
Pfeil 8.4.1 Die »Stack«-Klasse
Pfeil 8.5 Objektauflistungen im Überblick
Pfeil 8.6 Generische Auflistungsklassen
Pfeil 8.6.1 Die Interfaces der generischen Auflistungsklassen
Pfeil 8.6.2 Die generische Auflistungsklasse »List<T>«
Pfeil 8.7 Eigene Auflistungen mit »yield« durchlaufen


Galileo Computing - Zum Seitenanfang

8.3 Die Klasse »Hashtable« Zur nächsten ÜberschriftZur vorigen Überschrift

IList-Auflistungen verwalten ihre Elemente über Indizes. Dieses Konzept hat einen Nachteil: Wenn man nach einem bestimmten Element sucht und dessen Position nicht kennt, muss man die Liste so lange durchlaufen, bis man eine Übereinstimmung findet. Enthält die Auflistung sehr viele Einträge, kann das sehr zeitaufwendig sein und kostet Rechenleistung.

Kommt es nicht auf die Reihenfolge der Elemente an, kann man sich für eine Auflistung entscheiden, die das Interface IDictionary implementiert. Zu dieser Gruppe gehört die Klasse Hashtable, die in diesem Abschnitt vorgestellt wird. In IDictionary-Auflistungen kann ein bestimmtes Element zwar schnell gefunden werden, allerdings muss man dabei in Kauf nehmen, keinen Einfluss auf die Positionierung der Elemente in der Liste zu haben, denn die Elemente werden in einer für sie passenden Reihenfolge sortiert.


Galileo Computing - Zum Seitenanfang

8.3.1 Methoden und Eigenschaften der Schnittstelle »IDictionary« Zur nächsten ÜberschriftZur vorigen Überschrift

Die meisten der von IDictionary veröffentlichten Methoden sind uns bereits von der Schnittstelle IList her bekannt. Das erleichtert zwar einerseits die Einarbeitung, zwingt uns aber andererseits dennoch in einigen Fällen zu einer etwas genaueren Betrachtung. Jeder Listeneintrag in einer IDictionary-Auflistung wird durch ein Schlüssel-Werte-Paar beschrieben, was sich in der Parameterliste der Add-Methode niederschlägt:


void Add(object key, object value);

Der erste Parameter wird als Schlüssel für das hinzuzufügende Element verwendet und sorgt für die Identifizierbarkeit innerhalb einer Liste. Der zweite Parameter ist die Referenz auf das hinzuzufügende Element. Wir stoßen hier zum ersten Mal auf die Tatsache, dass von IDictionary-Auflistungen anstelle eines Index ein Schlüssel verwendet wird.

Der Schlüssel begleitet uns durch alle Methoden und wird auch von Remove verwendet, um ein Objekt aus der Auflistung zu entfernen:


void Remove(object key);

Da IDictionary-Objekte nicht über Indizes verwaltet werden, brauchen nach dem Löschen eines Elements etwaige Folgeelemente auch keine Lücke zu schließen.

Dem Indexer kommt nicht nur die Aufgabe zu, unter der Angabe des Schlüssels den Zugriff auf das gewünschte Element zu gewährleisten, vielmehr kann er auch dazu benutzt werden, den Wert eines Objekts zu verändern.


object this[object key] {get; set;}

Gibt man einen Schlüssel an, der sich noch nicht in der Auflistung befindet, wird das Element hinzugefügt. Dabei bleibt der Wert leer, ist also null, was durchaus zulässig ist.

Die Schlüssel und die Werte werden in eigenen Auflistungen verwaltet. Die Referenz auf diese internen Auflistungen liefern die Eigenschaften Keys und Values.


ICollection Keys {get;}
ICollection Values {get;}

Mit Clear kann eine IDictionary-Auflistung geleert werden, und mit Contains können Sie prüfen, ob ein bestimmter Schlüssel bereits in der Liste enthalten ist.

Um nach einem Element in einer IDictionary-Auflistung zu suchen, wird eine Schlüsselinformation benötigt, der ein Wert zugeordnet ist. IDictionary-Auflistungen enthalten Elemente mit Schlüssel-Wert-Kombinationen. Der Schlüssel muss eindeutig sein und darf nicht den Inhalt null haben.


Galileo Computing - Zum Seitenanfang

8.3.2 Beispielprogramm zur Klasse »Hashtable« topZur vorigen Überschrift

Die wichtigste Auflistung, die das IDictionary-Interface implementiert, wird von der Klasse Hashtable beschrieben. Im folgenden Beispiel wird eine Hashtabelle verschiedene Objekte vom Typ Artikel verwalten. Für die wichtigsten Eigenschaften und Methoden einer Hashtable werden in diesem Beispielprogramm jeweils separate Methoden bereitgestellt.


// ---------------------------------------------------------
// Beispiel: ...\Kapitel 8\HashtableSample
// ---------------------------------------------------------
class Artikel {
  public int Artikelnummer { get; set; }
  public string Bezeichner { get; set; }
  public double Preis { get; set; }
  public Artikel(int artNummer, string bezeichner, double preis) {
    Artikelnummer = artNummer;
    Bezeichner = bezeichner;
    Preis = preis;
  }
}

Listenelemente hinzufügen

Die Hashtable wird durch den Aufruf der Methode GetFilledHashtable mit mehreren Artikel-Objekten gefüllt. Im Gegensatz zur ArrayList (oder präziser ausgedrückt, zur IList) stellt Hashtable mit Add nur eine Methode zur Verfügung, um der Auflistung Objekte hinzuzufügen. Üblicherweise wird für den Schlüssel eine Zeichenfolge verwendet, obwohl der schlüsselbeschreibende erste Parameter vom Typ Object ist. Das soll auch in unserem Beispiel nicht anders sein, wir verwenden dazu den Bezeichner des Artikels.


//  Objekte der Hashtabelle hinzufügen
public static Hashtable GetFilledHashtable() {
  Hashtable hash = new Hashtable();
  Artikel artikel1 = new Artikel(101, "Wurst", 1.98);
  Artikel artikel2 = new Artikel(45, "Käse", 2.98);
  Artikel artikel3 = new Artikel(126, "Kuchen", 3.50);
  Artikel artikel4 = new Artikel(6, "Fleisch", 7.48);
  Artikel artikel5 = new Artikel(22, "Milch", 0.98);
  Artikel artikel6 = new Artikel(87, "Schololade", 1.29);
  hash.Add(artikel1.Bezeichner, artikel1);
  hash.Add(artikel2.Bezeichner, artikel2);
  hash.Add(artikel3.Bezeichner, artikel3);
  hash.Add(artikel4.Bezeichner, artikel4);
  hash.Add(artikel5.Bezeichner, artikel5);
  hash.Add(artikel6.Bezeichner, artikel6);
  return hash;
}

Listen der Schlüssel und Werte einer Hashtable

Zur Ausgabe aller Schlüsselwerte wird die Liste aller Schlüssel mit der Eigenschaft Keys abgerufen. Da wir für die Schlüssel Zeichenfolgen verwendet haben, kann die Laufvariable der Schleife vom Typ string sein.


// Ausgabe der Schlüsselliste
public static void GetKeyList(Hashtable hash) {
  foreach (string item in hash.Keys)
    Console.WriteLine(item);
}

Sehr ähnlich besorgen wir uns auch die Liste aller gespeicherten Werte. Die Werteliste wird von der Hashtable durch Aufruf der Eigenschaft Values bereitgestellt. Die Einzelwerte selbst sind in unserem Beispiel Artikel-Objekte, deren Eigenschaften wir in die Konsole schreiben.


// Ausgabe der Wertliste
public static void GetValueList(Hashtable hash) {
  foreach (Artikel item in hash.Values)
    Console.WriteLine("{0,-4}{1,-12}{2}", 
                item.Artikelnummer, item.Bezeichner, item.Preis);
}

Auf Listenelemente zugreifen

Wir haben bisher ganz ausdrücklich die in der Auflistung enthaltenen Schlüssel und Werte mit den Eigenschaften Keys und Values abgefragt. Nun interessiert uns ein Listeneintrag als Ganzes. Dabei treffen wir auf ein ganz besonderes Charakteristikum einer IDictionary-Auflistung, denn die Laufvariablen der Schleifen können nicht dazu benutzt werden, auf das Listenelement zuzugreifen. Daher wird zur Laufzeit eine Ausnahme ausgelöst, wenn Sie versuchen, die Laufvariable mit


// Achtung: Falscher Zugriff auf die Hashtable
foreach(Artikel item in hash)
  Console.WriteLine(item.Bezeichner);

auszuwerten oder mit


// Achtung: Falscher Zugriff auf die Hashtable
foreach(object item in hash)
  Console.WriteLine(((Artikel)item.Bezeichner;

zu konvertieren.

Um auf ein Listenelement in einer foreach-Schleife zugreifen zu können, müssen Sie die Laufvariable vom Typ DictionaryEntry deklarieren. Von diesem Typ sind die Elemente in einer Hashtable. DictionaryEntry ist eine Struktur, die das Schlüssel-Wert-Paar für einen Hashtabelleneintrag enthält. Über die Eigenschaften Key und Value können wir die notwendigen Informationen beziehen. Während uns Key nur den Schlüssel liefert, können wir über den Rückgabewert von Value nach vorheriger Typumwandlung auf das Objekt zugreifen:


// Schlüssel-Wert-Paar über ein DictionaryEntry-Objekt ausgeben
public static void GetCompleteList(Hashtable hash) {
  foreach (DictionaryEntry item in hash) {
    Console.Write(item.Key);
    Console.WriteLine(" - {0}", item.Value);
  }
}

Prüfen, ob ein Element bereits zur Hashtable gehört

Eine Hashtable dient zur Verwaltung mehrerer meist gleichartiger Objekte und hat im Vergleich zu anderen Auflistungen den Vorteil, einen sehr schnellen Zugriff über den Indexer zu ermöglichen. Manchmal interessiert auch die Antwort auf die Frage, ob in einer Hashtable bereits ein bestimmtes Element eingetragen ist. Sie können dabei so vorgehen, dass Sie entweder nach einem Schlüssel suchen oder nach einem bestimmten Wert.

Beginnen wir mit der Suche nach einem Schlüssel. Hierzu können wir zwei Methoden benutzen, die gleichwertig sind: Contains und ContainsKey. Beide liefern als Resultat einen booleschen Wert zurück.


// prüfen, ob ein bestimmter Schlüssel enthalten ist
public static void SearchForKey(Hashtable hash) {
  string text = "\n\nGeben Sie das auszuwertende Element an: ";
  string input;
  do {
    Console.Write(text);
    input = Console.ReadLine();
    // prüfen, ob sich der Schlüssel in der Hashtabelle befindet
    if (hash.Contains(input))
      Console.WriteLine("ArtikelNr.: {0,-4} Preis: {1}", 
                          ((Artikel)hash[input]).Artikelnummer, 
                          ((Artikel)hash[input]).Preis);
    else
      Console.WriteLine("Nicht Element der Hashtable");
    Console.WriteLine("Zum Beenden F12 drücken ...");
  }
  while (Console.ReadKey(true).Key != ConsoleKey.F12);
}

Nicht nur über den Schlüssel lässt sich prüfen, ob ein Element Mitglied der Hashtabelle ist. Auch über den booleschen Rückgabewert von ContainsValue ist das möglich. Hierzu dient im Beispielprogramm die benutzerdefinierte Methode SearchForValue. Dieser Methode wird neben der Referenz auf die Auflistung auch noch das Artikel-Objekt übergeben, dessen Eintrag in der Liste zu prüfen ist.


// prüfen, ob die Liste einen bestimmten Wert enthält
public static void SearchForValue(Hashtable hash, Artikel artikel) {
  if (hash.ContainsValue(artikel))
    Console.WriteLine("Das Objekt '{0}' ist enthalten.", 
                                            artikel.Artikelnummer);
  else
    Console.WriteLine("Das Objekt '{0}' ist nicht enthalten.", 
                                            artikel.Artikelnummer);
}

Testen der Methoden

Zum Schluss zeige ich Ihnen an dieser Stelle auch noch das Beispielprogramm, in dem die zuvor gezeigten Methoden aufgerufen werden. Am Ende des Programms wird die Methode SearchForValue aufgerufen, um nach einem bestimmten Artikel zu suchen. Dabei wird ein neues Artikel-Objekt mit Daten erzeugt, die sich bereits in der Liste befinden. Trotzdem wird zur Laufzeit festgestellt, dass das Objekt noch kein Mitglied der Liste ist. Das Ergebnis verwundert nicht, da von unserer Hashtable nach Objektreferenzen bewertet wird, und nicht nach den darin enthaltenen Daten.

Abbildung 8.4 Ausgabe des Beispielprogramms »HashtableSample«


static void Main(string[] args){
  Hashtable hash = GetFilledHashtable();
  // Liste der Schlüssel ausgeben
  Console.WriteLine("===== Schlüsselliste =====");
  GetKeyList(hash);
  // Liste der Werte ausgeben
  Console.WriteLine();
  Console.WriteLine("===== Werteliste =====");
  GetValueList(hash);
  // Liste der Schlüssel und Werte ausgeben
  Console.WriteLine();
  Console.WriteLine("===== Schlüssel-Werte-Paare =====");
  GetCompleteList(hash);
  // Suchen nach einem bestimmten Schlüssel
  SearchForKey(hash);
  // Suchen nach einem bestimmten Wert
  SearchForValue(hash, new Artikel(45, "Käse", 2.98));
  Console.ReadLine();
}



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  Zum Katalog
Zum Katalog: Visual C# 2010

Visual C# 2010
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchempfehlungen
Zum Katalog: Professionell entwickeln mit Visual C# 2012






 Professionell
 entwickeln mit
 Visual C# 2012


Zum Katalog: Windows Presentation Foundation






 Windows Presentation
 Foundation


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: C/C++






 C/C++


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2010
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern