No. 239Marcel Gnoth, NTeam GmbH
DatenstrukturenDas Framework der Jäger und Sammler
Zur Person
Dipl. Inf. Marcel Gnoth, MCSDwww.gnoth.net
NTeam GmbH, Berlinwww.nteam.de
Senior Consultant, TrainerVB6, COM, DatenbankenVerteilte InformationssystemeUnd ....
.Net
Inhalt
EinführungInterfaces – der CollectionsCollections – Klassen im
FrameworkCollections – selbstgemacht Sortieren – im Framework AlternativenZusammenfassung
Einführung
Für Jäger und Sammler
Die gute alte Zeit ........
VB 6ArraysVB - Collection
Scripting RuntimeDictionary
.......und Heute ?
Array System.Array
CollectionDictionary
System.Collections...
Microsoft.VisualBasic.Collection
Collection – Klassen in .NetEine Menge von Klassen, die
verschiedene Interfaces implementieren
NamespacesSystem.CollectionsSystem.Collections.SpecializedMicrosoft.VisualBasic.Collection
Interfaces
Was müssen Collections bieten?
Interfaces ÜbersichtIEnumerable, IEnumeratorICollectionIListIDictionaryIComparableIComparer
IEnumerable
ICollection
IList IDictionary• Index • Key
• For Each Support
• Count, CopyTo
Interfaces I
IEnumerableFor Each SupportGetEnumerator()
ICollection Inherits IEnumerableAbzählen, Synchronisation, in Array
kopierenCopyTo(), Count,
IsSynchronized, SyncRoot
Interfaces IIIList Inherits ICollection,
IEnumerableMenge von Elementen, Zugriff über IndexIsReadOnly, IsFixedSizeAdd( ), Insert( )Contains(), IndexOf()Clear( ), Remove( ), RemoveAt( )
Interfaces IIIIDictionary Inherits ICollection,
IEnumerableEnthält DictionaryEntry – ElementeZugriff über Schlüssel IsFixedSize, IsReadOnly Keys, Values Add( ), Remove( ) Clear( ), Contains( )
Interfaces IV
IComparable, IComparerSortieren von ObjektenSpäter....
Collections
Wir schreiten zur Tat...
Übersicht Collections
0 - basiertViele haben:
Constructor der ICollection akzeptiertAddRange, RemoveRange
DataSourceIndexer
VB: myObj = Col.Item( 7 )C#: myObj = Col [ 7 ]
Übersicht I – Klassisch Name Index /
KeyKey eind.
Typ Bemerkung
Array Index - Object
0 basiert
ArrayList Index - Object
Ändert Größe dynamisch, IList
CollectionBase Index - Typed Selbstgemachte Collections
Hashtable Key Ja Object
IDictionary
DictionaryBase Key Ja Typed Selbstgemachte Dictionaries
ListDictionary Key Ja Object
Verkettete Liste, für Count <11
HybridDictionary Key Ja Object
Mix Hashtable + ListDictionary
SortedList Index + Key Ja Object
Sortiert nach Keys
Collection Index + Key Ja Object
„alte“ VB-Collection
NameValueCollect.
Index + Key Nein String Ein Key für mehrere Strings
NameObject-CollectionBase
Index + Key Nein Typed Eigene NameObjectCollections
StringCollection Index - String
StringDictionary Key Ja String
Übersicht II – Die Exoten
Name Typ Bemerkung
Queue Object First in First out
Stack Object Last in First out
BitArray Bits
BitVektor Bits 32 Bits in einer Struktur, schnell
DataSet Daten Keine Objektreferenzen
XMLDocument Daten Keine Objektreferenzen
ArraySystem.Array
Rank: Anzahl der DimensionenLength: Anzahl Elemente absolutGetLength(n): Anzahl Elemente einer
DimensionClone, Reverse
Kann Inhalt sortierenBinäre Suche auf sortierten ElementenGröße kann nicht verändert werdenImplementiert IList
ArrayErzeugen...
VB
C#
foreach (C#)
long[]row = {0,1,2,3};
long[]row = new long[4];
long[]row = new long[]{0,1,2,3};
Dim row()As Integer = {0,1,2,3}
Dim row(4)As Integer
foreach (int ID in colArr){ID=4;
}
ArrayList I
Eindimensionales ArrayKann wachsen und schrumpfen
Capacity, TrimToSizeAdd, AddRange, Insert, InsertRangeRemove, RemoveAt, RemoveRange
Kann Elemente sortieren, suchenZugriff über Index
ArrayList II
ArrayList.Adapter generiert Wrapper für IList ObjekteNutzen der ArrayList Methoden
Einsatz:Schnell, effizient, nur IndexSo oft wie möglich
DemoArrayList.Adapter
DemoArrayList.Adapter
HashTable
PropertiesCountKeys, Values
MethodenAdd, RemoveContainsKey, ContainsValue
Standard IDictionary Implementierung
Keine Sortierung
Hashtable
HashcodeFür jeden Eintrag wird Hashcode
berechnetAnhand des Hashcodes werden
Objekte einsortiertElemente sind nicht in Reihenfolge
ihres Einfügens angeordnetDurch Hashcode schnelles Suchen
HashtableDictionaryEntry
Values
foreach (DictionaryEntry e in colDic) { Console.Write("{0}/{1} ", e.Key,e.Value); }
foreach (CCustomer c in colCustDB.Values){Console.Write(c.Caption);
}
HashTableEinsatz:
Viele ObjekteZufällige / ungeordnete Zugriffe Zugriff über eindeutigen KeyLangsamer als ArrayList
ListDictionary
Einfache Implementierung von IDictionary
verkettete ListeWenig OverheadEmpfohlen für kleine Collections
(<11)Sehr langsam bei Count > 1000
Hashtable benutzen!!System.Collections.Specialized
HybridDictionary
Verwaltet kleine Mengen in ListDictionary
Wechselt automatisch zu Hashtable wenn Collection zu groß wird
System.Collections.Specialized
SortedList
Kreuzung aus Hashtable und ArrayIList und IDictionary
Sortiert nach den KeysZugriff über Key und IndexIntern zwei Arrays für Keys und
ValuesBisschen langsamer als HashtableSehr vielseitig
SortedList
PropertiesItem (Index / Key)CapacityKeys, Values
MethodenAdd, Remove, RemoveAtContainsKey, ContainsValueIndexOfKey, IndexOfValue
VisualBasic.CollectionIn C# Referenz auf
„Microsoft.VisualBasic“ setzen
In VB:
Verhält sich wie die gute alte VB Collection
Zugriff über Index oder KeyAchtung !!! 1 – basiert !!!
private Microsoft.VisualBasic.Collection colVB;
Dim colVB As Collection = New Collection()
VisualBasic.Collection
KompatibilitätsgründeLangsamer als ArrayList und
Hashtable
String Dictionary / CollectionSystem.Collections.Specialized
StringCollectionCollection für Strings
StringDictionaryHashtable für Strings
Queue / StackQueue
First In First OutEnqueue( ) / Dequeue( )
StackLast In First OutPush( ), Pop( )
Gemeinsame Eigenschaften / MethodenPeek( ), Contains( ) ToArray( ), Count
Können mit foreach durchlaufen werden
BitArray / BitVektor
Verwalten BitfelderBitVektor
Struktur, auf dem Stack (Wert-Typ)32 BitsEffizienter als BitArray
Logische Operationen auf den Bits
Dim myBA2 As New BitArray(5, False)Dim myBytes() As Byte = {1, 2, 3, 4, 5}Dim myBA3 As New BitArray(myBytes)Dim myBools() As Boolean = {True, False, True, True, True}Dim myBA4 As New BitArray(myBools)
NameValueCollectionKeys und Values sind StringsZugriff über Key oder IndexMehrere Values können den
gleichen Key habenKey nicht eindeutig!
Gruppiert nach Keysforeach (string k in nv.AllKeys)
Debug.WriteLine(k + ": " + nv[k]);
Key1: Anna,Barbara,ClaudiaKey2: Doris,ErnaKey3: Frida,Gabi,Helga,IngaKey4: Karla
DemoNameValueCol.
DemoNameValueCol.
Collections – selbstgemacht
So schmeckt es immer noch am besten!
Eigene Collection-KlassenAbstrakte Klassen im Framework
ReadOnlyCollectionBaseCollectionBaseDictionaryBaseNameObjectCollectionBase
Eigene Klassen davon ableiten (Vererbung)
Keine Aggregation mehr wie in VB6
oder alles selber machen
CollectionBaseArrayList für eigene typisierte
CollectionsÜber InnerList Property Zugriff
auf ArrayList MemberZugriff über Index
CollectionBase Implementierung
public class CCustomersColBase: CollectionBase { //Konstruktor der Basisklasse aufrufen public CCustomersColBase() : base() { } public void Add(CCustomer Cu) { this.InnerList.Add(Cu); } public void Remove(int x){ this.InnerList.RemoveAt(x); } public CCustomer this[int x] { //Indexer get {return (CCustomer) InnerList[x];} }}
foreach (CCustomer cu in colCustCB){ cu.Caption = "Hallo";}
DictionaryBase
Hashtable für eigene typisierte Collections
InnerHashtableZugriff über Key
DictionaryBase Implementierungpublic class CCustomersDicBase: DictionaryBase { //Konstruktor der Basisklasse aufrufen public CCustomersDicBase() : base() { } public void Add(CCustomer Cu, string k){ this.InnerHashtable.Add(k,Cu); } public void Remove(string Key){ InnerHashtable.Remove(Key); } //Support für spezielles foreach public System.Collections.ICollection Values { get {return this.InnerHashtable.Values;} } //Indexer public CCustomer this[string Key] { get {return (CCustomer) InnerHashtable[Key];} }}
DictionaryBase Zugriff
DictionaryEntry
ICollection Valuesforeach (CCustomer c in colCustDB.Values){
Console.Write (c.Caption);}
foreach (DictionaryEntry d in colCustDB){Console.Write (d.Key + d.Value);
}
NameObjectCollectionBase
Intern eine HashtableZugriff über Index oder KeyGruppiert nach KeysKeys sind StringsKeys können mehrfach vorkommen
Haben mehrere Objekte den gleichen Key, dann bei Zugriff über Key nur das erste Objekt
Über Index Zugriff auf alle Objekte
DemoNameObjColBase
DemoNameObjColBase
Indexer in C#
public CCustomer this[string Key] { get {return (CCustomer) this.BaseGet(Key);}}
public CCustomer this[int Index] { get {return (CCustomer) this.BaseGet(Index);}}
Indexer in VB.NetPublic ReadOnly Property Item(ByVal Index As Integer) _
As CCustomer Get Return CType(Me.InnerList(DBID), CCustomer) End GetEnd Property
Public ReadOnly Property Item(ByVal Key As String) _As CCustomer
Get Return CType(Me.InnerHashtable(Key), CCustomer) End GetEnd Property
Collection – selbstgemachtEigene Collection-Klasse definierenmuß Interfaces implementieren
Mindestens IEnumerable
public class Tokens : IEnumerable{ private string[] elements; public Tokens(string source, char[] delim){ elements = source.Split(delimiters); } public IEnumerator GetEnumerator() { return new TokenEnumerator(this); }}
IEnumerator IEnumerable.GetEnumerator
muß Enumerator zurückgeben
Kann selbst implementiert werdenNur in besonderen AnwendungsgebietenReihenfolge bei foreach verändern .............
IEnumerator - Beispiel
private class TokenEnumerator : IEnumerator { private int position = -1; private Tokens t; public TokenEnumerator(Tokens t) { this.t = t; } public bool MoveNext() { if (position < t.elements.Length - 1) { position++; return true;} else {return false;} } public void Reset() { position = -1; } public object Current { get {return t.elements[position];} }} Demo
Tokens-Collection
DemoTokens-Collection
Sortieren im Framework
Auf die Reihenfolge kommt es an!
SortierenArray, ArrayList und andere
können Objekte sortierenEntweder...
die Objekte implementieren selbst Interface IComparable
...oder...Extra Klassen für ein Objekt, die
IComparer implementierenImmer wenn es im Framework
etwas zu sortieren gibt, werden diese Interfaces benutzt
IComparableIn der Klasse selbst, eine Methode
CompareToArray.Sort ( )
public class CCustomer : IComparable {...//IComparable nach Caption int IComparable.CompareTo(object oCu){ CCustomer Cu = (CCustomer) oCu; return String.Compare
(this.Caption,Cu.Caption); }}
IComparerSeparate Klassen, eine Methode:
CompareArray.Sort (new CustSortByName)
DemoSortieren
DemoSortieren
public class CustSortByName : IComparer { public CustSortByName() { } public int Compare(object obj1,object obj2){ CCustomer cu1 = (CCustomer) obj1; CCustomer cu2 = (CCustomer) obj2; return String.Compare
(cu1.Nachname,cu2.Nachname); }}
Alternativen
Der andere Weg zur Sammlung:DataSetXMLDocument
ADO.Net DataSet
Sehr flexible DatenstrukturKann ohne Verbindung zu einer
Datenbank erzeugt werden
Dataset - Füllen
Mehrere Methoden zum Füllendt.Rows.Adddt.LoadDataRow
foreach (CCustomer xc in source_arrL){ dt.LoadDataRow( new object[] {xc.ID, xc.Key, xc.Nachname, xc.Vorname, xc.Land, xc.Alter}, true);}
DataSet - Zugriff
ZugriffDataTable.Rows.Contains;DataTable.Rows[Index]DataRow = DataTale.Rows.FindDataRow[ ] = DataTable.Select
foreach (int ID in Indicies){ cap = dt.Rows[ID].ItemArray[2].ToString();}
DataSet
gut für Relationale Datenkann mehrere Tabellen enthaltenkann Foreign Key und Unique
Constraints verwaltenErzeugen von Views Filtern und Sortierensehr mächtige Funktionen
DemoDataSet
DemoDataSet
XMLDocument
viel XML in .NetXML hat einen gewissen Overheadgut für hierarchische Datenleicht zu erzeugenkann leicht visualisiert werden
XSLTkomplexe Abfragesprache XPath
XMLDocumentErzeugen aus DataSet
Abfrage eines Knotens
Select über alle Knoten
XMLDocument xmlCustomers = new XmlDocument();xmlCustomers.LoadXml(dsCustomers.GetXml());
DemoDataSet
DemoDataSet
s = "Customer[Key = \"K10\"]";XmlNode xn = xmlCustomers.SelectSingleNode(s);
s = "/Customers/Customer[Land ='PERU']";XmlNodeList xl = xmlCustomers.SelectNodes(s);
Schlußfolgerungen
Und nun?
ZusammenfassungDie wichtigsten Typen
Array, ArrayList (Index)Hashtable (Key)SortedList (Index und Key)
Collectionbase, DictionaryBaseString Collection / Dictionary
Nicht vergessenDataSetXML-Document
Performance
Durchschnitt aus 3 TestsWer misst, misst Mist!
Garbage Collection schlägt ab und zu zu
Dadurch schwanken die Werte
Die richtige Auswahl des Collection – Typs ersetzt kein gutes Design!
Laden 10001.000 Objekte laden
0,0020,0040,0060,0080,00
100,00120,00140,00160,00180,00200,00
Arra
yFix
edLe
ngth
Arra
yLis
t
Que
ue (e
nque
ue)
Sta
ck (p
ush)
Has
hTab
le
Sor
tedL
ist
List
Dic
tiona
ry
Hyb
ridD
ictio
nary
Nam
edV
alue
Col
lect
ion
VB
Col
lect
ion
CC
ustD
icB
ase
Cus
tCol
Bas
e
Cus
tNam
edO
bjC
olB
ase
Stri
ngC
olle
ctio
n
Stri
ngD
ictio
nary
Dat
aset
(Loa
dDat
aRow
)
Dat
aset
(Row
s.A
dd)
XM
LDoc
umen
t (au
s
Tic
ks (m
s)
1.000 Objekte
Laden 30.00030.000 Objekte laden
0,00
500,00
1000,00
1500,00
2000,00
2500,00
Arr
ayFi
xedL
engt
h(S
etva
lue)
Arr
ayLi
st
Que
ue (e
nque
ue)
Sta
ck (p
ush)
Has
hTab
le
Sor
tedL
ist
List
Dic
tiona
ry
Hyb
ridD
ictio
nary
Nam
edV
alue
Col
lect
ion
VB
Col
lect
ion
CC
ustD
icB
ase
Cus
tCol
Bas
e
Cus
tNam
edO
bjC
olB
ase
Stri
ngC
olle
ctio
n(S
tring
s)S
tring
Dic
tiona
ry(S
tring
s)
Dat
aset
(Loa
dDat
aRow
)
Dat
aset
(Row
s.A
dd)
XM
LDoc
umen
t (au
sD
atas
et)
Tick
s (m
s)
Zufälliger ZugriffZufälliger Zugriff (30.000)
0,00
100,00
200,00
300,00
400,00
500,00
Arr
ay (
Index)
Arr
ayLis
t (I
ndex)
Queue (
Dequeue)
Sta
ck (
Pop)
HashT
able
(K
ey)
HashT
able
(C
onta
insK
ey)
Sort
edLis
t (K
ey)
Sort
edLis
t (G
etB
yIn
dex)
Sort
edLis
t (C
onta
insK
ey)
HybridD
ictio
nary
(K
ey)
HybridD
ictio
nary
Nam
eV
alu
eC
olle
ctio
n (
Index)
Nam
edV
alu
eC
olle
ctio
n (
Key)
Nam
eV
alu
eC
olle
ctio
nV
B-C
olle
ctio
n (
Index)
VB
-Colle
ctio
n (
Key)
CC
usto
mers
Dic
Base (
Key)
CC
usto
mers
ColB
ase (
Index)
CC
ustu
mers
Nam
eO
bjC
olB
ase
CC
ustu
mers
Nam
eO
bjC
olB
ase
Str
ingC
olle
ctio
n (
Index)
Str
ingD
ictio
nary
(K
ey)
Data
set (R
ow
s[Index])
Data
set (R
ow
s.F
ind)
Data
set (S
ele
ct+
Sort
=#196
XM
LD
ocum
ent
XM
LD
ocum
ent
Tic
ks (
ms)
Zufälliger Zugriff (30.000)
Array (Index) 00,00
ArrayList (Index) 10,00
Queue (Dequeue) 03,33
Stack (Pop) 03,33
HashTable (Key); 43,33
HashTable (ContainsKey) 26,67
SortedList (Key) 387,67
SortedList (GetByIndex) 03,33
SortedList (ContainsKey) 377,33
HybridDictionary (Key) 37,00
HybridDictionary (ContainsKey) 30,00
NameValueCollection (Index) 20,00
NamedValueCollection (Key) 70,00
NameValueCollection (GetKey) 10,00
Zufälliger Zugriff (30.000)VB-Collection (Index) 50,00
VB-Collection (Key) 130,00
CCustomersDicBase (Key) 36,67
CCustomersColBase (Index) 10,00
CCustumersNameObjColBase (Index) 13,33
CCustumersNameObjColBase (Key) 66,67
StringCollection (Index) 10,00
StringDictionary (Key) 73,33
Dataset (Rows[Index]) 104,00
Dataset (Rows.Find) 397,00
Dataset (Select+Sort=#196 Rows) 220,33
XMLDocument (SelSingleNode,#150) 16.066,67
XMLDocument (SelectNodes=#196) 0,00
Links
Code zum Vortraghttp://www.gnoth.net/BASTA/Feb02.ht
m
Dr. GUI von http://msdn.microsoft.com/ In der MSDN nach „Dr. GUI.NET #4“
suchen
Fragen?
Uff...Uff...