Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Die Hashtable Klasse

Geschrieben von: Christoph Wille
Kategorie: ASP.NET

Neben Arrays für Elementzugriff via Index konnte man in VBScript mit Hilfe der Dictionary Komponente den Elementzugriff mittels Schlüssels (Key) bewerkstelligen. Obwohl die Komponente ihren Zweck erfüllte, hatte sie einen großen Nachteil - sie war nicht für den Serverbetrieb entwickelt worden, und konnte schnell mal einen ASP Server in die Knie zwingen.

Mit ASP.NET und dem .NET Framework kommen etliche neue Collection Klassen (diese sind freundlicherweise im System.Collections Namespace beheimatet). Unter anderem mit dabei ist die Hashtable Klasse, die einige neue (hilfreiche) Funktionen mitbringt, die ich Ihnen heute anhand von Beispielen näherbringen möchte.

Voraussetzung um den Sourcecode dieses Artikels verwenden zu können ist eine Installation des Microsoft .NET Framework SDK's auf einem Webserver. Weiters setze ich voraus, daß der Leser die Programmiersprache C# zu einem gewissen Grad beherrscht - es finden sich etliche Artikel auf diesem Server, um das notwendige Wissen zu erlernen.

Befüllen und Auslesen

Starten wir mit den einfachen Dingen des Lebens - dem Befüllen eines Hashtables sowie dem darauffolgenden Auslesen und Ausgeben der Schlüssel/Wert Paare. Der folgende Sourcecode ist als Datei dumptable.aspx im Download des heutigen Artikels enthalten.

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
Hashtable table = new Hashtable();
table.Add("aspgerman@ls.asplists.com","AspGerman");
table.Add("aspdedotnet@ls.asplists.com","aspDEdotnet");
table.Add("aspdedatabase@ls.asplists.com","aspDEdatabase");
table.Add("aspdebeginners@ls.asplists.com","aspDEbeginners");

Response.Write("<table><tr><th>Key</th><th>Value</th></tr>");
foreach (DictionaryEntry de in table)
{
	Response.Write("<tr><td>" + de.Key + 
	   "</td><td>" + de.Value + 
	   "</td></tr>");
}
Response.Write("</table>");
%>

Zuerst importiere ich den System.Collections Namespace um die Hashtable Klasse verwenden zu können. In der ersten Zeile des tatsächlichen Codes erzeuge ich eine Instanz der Klasse, und beginne danach den Hashtable mit Schlüssel/Wert Paaren aufzufüllen. Insgesamt speichere ich vier Einträge vom Typ String, allerdings nehmen alle Funktionen der Hashtable Klasse den Typ object entgegen - also man kann wirklich alles darin speichern.

Das Auslesen funktioniert über das ICollection Interface der Hashtable Klasse. Für jeden Eintrag bekomme ich eine DictionaryEntry Struktur geliefert, die zwei Eigenschaften für mich bereitstellt: Key und Value. Das reicht mir, um eine schöne Tabelle auszugeben.

Es heißt ja, daß viele Wege nach Rom führen. Stimmt. Also muß es auch einen anderen Weg geben, um den Inhalt des Hashtables auszugeben. Dieser ist zwar etwas "steiniger", aber manchmal vielleicht sogar leistungsfähiger (dumptableviacoll.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
Hashtable table = new Hashtable();
// befüllen des hash tables - exkludiert

ICollection iKeys = table.Keys;

object[] arrValues = new object[table.Values.Count];
table.Values.CopyTo(arrValues,0);

int nElement = 0;
Response.Write("<table><tr><th>Key</th><th>Value</th></tr>");
foreach(object theKey in iKeys)
{
	Response.Write("<tr><td>" + theKey + 
	     "</td><td>" + arrValues[nElement++] + 
		 "</td></tr>");
}
Response.Write("</table>");
%>

Den Code für das Befüllen habe ich in diesem Listing ausgelassen (ebenso in den folgenden, um die Übersichtlichkeit zu erhöhen). Das Hauptaugenmerk möchte ich auf die Eigenschaften Keys und Values der Hashtable Klasse legen, welche mir beide ein ICollection Interface liefern, über das ich object Daten auslesen kann.

Mit einer ICollection kann ich das foreach Statement ja locker verwenden, allerdings was ist, wenn ich 2 Collections gleichzeitig auslesen muß? So einfach geht das dann nicht mehr.

Es sind zwar beide Collections nicht sortiert, aber die zugehörigen Schlüssel und Werte sind immer an den gleichen Positionen. Und wenn ich eine Collection in ein Array umwandle, dann kann ich mir ja zum aktuellen Element der einen Collection das dazupassende aus dem Array der anderen holen. Und genau das macht mein Sourcecode (Kurzversion):

ICollection iKeys = table.Keys;
object[] arrValues = new object[table.Values.Count];
table.Values.CopyTo(arrValues,0);

int nElement = 0;
foreach(object theKey in iKeys)
{
	Response.Write(theKey)
	Response.Write(arrValues[nElement]);
	nElement++;
}

Die CopyTo Methode erwartet ein Array sowie den Index, ab dem aus der Collection kopiert werden soll. Ab dann ist es "nur" mehr ein etwas verwinkelter Code, aber mit dem Dictionary unter ASP mußte man ähnlich tricksen. Apropos: ich hätte auch beide Collections in Arrays umwandeln können, allerdings wäre dann der Lerneffekt des Koppelns von Collection und Array ausgeblieben.

Suchen im Hashtable

Das simple Auslesen (aka Dumpen) habe ich jetzt genügend breitgetreten sodaß wir uns nun dem Suchen von Werten in einem Hashtable widmen können. Das Besondere an Dictionaries bzw der Hashtable Klasse ist ja der, daß die Schlüssel durch einen Hash repräsentiert werden, der extrem schnell auffindbar ist. Und genau das machen sich die nun vorgestellten Methoden zu Nutze (lookups.aspx):

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
Hashtable table = new Hashtable();
// befüllen des hash tables - exkludiert

// Anzahl der Element in der Collection
int nElementCount = table.Count;

// existiert der Schlüssel?
bool bKeyCont = table.ContainsKey("aspgerman@ls.asplists.com");

// existiert der Wert?
bool bValueCont = table.ContainsValue("aspDEdotnet");

// Element korrekt suchen
if (true == bKeyCont)
{
  Response.Write(table["aspgerman@ls.asplists.com"].ToString());
}
%>

Zu Demonstrationszwecken lese ich in diesem Beispiel auch die Anzahl der Elemente aus - mit Hilfe der Count Eigenschaft. Dann geht es aber schon zum Business: die Funktion ContainsKey liefert einen boolschen Rückgabewert, der angibt, ob ein bestimmter Schlüssel existiert. Diese Funktion sollte man unbedingt immer dann aufrufen, wenn man ein Element auslesen, löschen oder updaten möchte. Sonst droht eine Exception, falls das Element nicht da sein sollte (und sei es nur, weil man ein null Objekt dereferenziert).

Eine Funktion, die hin und wieder auch ganz nützlich sein wird, ist ContainsValue. Damit kann man nach einem Wert suchen lassen, und anhand des Rückgabewerts entscheiden, ob man ein Element schon im Hashtable hat oder nicht.

Der interessante Part ist aber das Auslesen des Werts:

object var = table[key];

Man geht einfach mit dem Schlüsselwert in den Item Indexer der Hashtable Klasse und bekommt den Wert oder eine Exception. Mit diesem Indexer kann man sowohl Werte auslesen als auch updaten - und damit kommen wir auch schon zur nächsten Sektion.

Updaten und Löschen

Üblicherweise befüllt man eine Collection nicht nur, sondern man möchte auch Werte ändern und sogar löschen können. Das kann die Hashtable Klasse natürlich auch - wie im folgenden Beispiel gezeigt (various.aspx).

<% @Page Language="C#" %>
<% @Import Namespace="System.Collections" %>
<%
Hashtable table = new Hashtable();
// befüllen des hash tables - exkludiert

// existiert der Schlüssel?
bool bKeyCont = table.ContainsKey("aspgerman@ls.asplists.com");

// Element korrekt updaten
if (true == bKeyCont)
{
  table["aspgerman@ls.asplists.com"] = "Hot Topics";
}

// Element löschen; existiert es nicht --> Exception
table.Remove("aspgerman@ls.asplists.com");

// und jetzt löschen wir alles
table.Clear();
%>

Die Methode ContainsKey ist bereits ein alter Bekannter, ebenso wie der Indexer - nur daß ich ihn hier zum Ändern des Wertes verwende. Ebenso einfach ist die Verwendung der Remove Methode, die ein einzelnes Element anhand des Schlüssels aus dem Hashtable entfernt. Last but not least bleibt mir die Clear Methode zu erklären: diese löscht sämtliche Elemente aus dem Hashtable.

Ein Blick auf die Konstruktoren

Eigentlich sollte man Konstruktoren am Anfang erklären, da sie ja als erstes aufgerufen werden, wenn man eine Instanz einer Klasse erstellt. Im Falle der Hashtable Komponente sind diese aber etwas komplexer, und man wird außer dem Standardkonstruktor die anderen im normalen Alltagsgebrauch nicht einsetzen - deshalb die Erklärung sozusagen als Anhang.

Die Hashtable Komponente hat im Moment elf verschiedene Konstruktoren. Die wichtigsten Merkmale dieser sind wie folgt:

  • Man kann die anfängliche Kapazität definieren (um den Speicher besser zu nutzen)
  • Der Load Factor kann definiert werden (balanciert Suchgeschwindigkeit und Speicherkonsumation)
  • Der Hash Code Provider kann gewählt werden (die Art und Weise, wie der Hash des Schlüssels gerechnet wird)
  • Der Vergleichsprovider kann gewählt werden (für Zugriffe auf Elemente)
  • Daten aus Dictionaries können übernommen werden (aus Datenbankzugriffen, zB)

Wie gesagt, diese Konstruktoren sind bei zu erwartender größerer Auslastung des Hashtables auf alle Fälle einen Blick wert.

Schlußbemerkung

Der heutige Artikel hat sich mit den Grundlagen einer der wichtigsten Collections unter dem .NET Framework gewidmet: der Hashtable Klasse. Diese wird immer dann zum Einsatz kommen, wenn man auf Elemente per Schlüssel und nicht per Index zugreifen muß - und das möglichst schnell.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Arrays mit Index und Schlüssel
Collections einmal anders: Stacks und Queues
Das foreach Statement
Datentypen in C#
Debugging in der Tiefe
Exception Handling in C#
On-the-fly Erstellung von vCard's
Verwendung von Arrays in C#
WHOIS Abfragen a la .NET

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.