.NET-Datenstrukturen:
Mehr zum Gespräch darüber, warum ArrayList und List tatsächlich unterschiedlich sind
Arrays
Wie ein Benutzer angibt, sind Arrays die "Old School" -Sammlung (ja, Arrays werden als Sammlung betrachtet, obwohl sie nicht Teil davon sind System.Collections
). Aber was ist "alte Schule" an Arrays im Vergleich zu anderen Sammlungen, dh denen, die Sie in Ihrem Titel aufgeführt haben (hier ArrayList und List (Of T))? Beginnen wir mit den Grundlagen, indem wir uns Arrays ansehen.
Zu Beginn sind Arrays in Microsoft .NET "Mechanismen, mit denen Sie mehrere [logisch verwandte] Elemente als eine einzige Sammlung behandeln können" (siehe verknüpften Artikel). Was bedeutet das? Arrays speichern einzelne Elemente (Elemente) nacheinander im Speicher mit einer Startadresse. Mit dem Array können wir leicht auf die sequentiell gespeicherten Elemente zugreifen, die an dieser Adresse beginnen.
Darüber hinaus können Arrays im Gegensatz zur Programmierung von 101 gängigen Konzepten sehr komplex sein:
Arrays können eindimensional, mehrdimensional oder jaddiert sein (gezackte Arrays sind lesenswert). Arrays selbst sind nicht dynamisch: Nach der Initialisierung reserviert ein Array mit einer Größe von n genügend Speicherplatz für n Objekte. Die Anzahl der Elemente im Array kann nicht wachsen oder schrumpfen. Dim _array As Int32() = New Int32(100)
reserviert genügend Speicherplatz auf dem Speicherblock, damit das Array 100 Objekte vom Typ Int32 primitiv enthält (in diesem Fall wird das Array so initialisiert, dass es Nullen enthält). Die Adresse dieses Blocks wird an zurückgegeben _array
.
Gemäß dem Artikel erfordert die Common Language Specification (CLS), dass alle Arrays auf Null basieren. Arrays in .NET unterstützen Arrays, die nicht auf Null basieren. Dies ist jedoch weniger häufig. Aufgrund der "Gemeinsamkeit" von Null-basierten Arrays hat Microsoft viel Zeit damit verbracht, ihre Leistung zu optimieren . Daher sind eindimensionale, nullbasierte (SZs) Arrays "speziell" - und wirklich die beste Implementierung eines Arrays (im Gegensatz zu mehrdimensionalen usw.) -, da SZs spezifische Anweisungen für die Zwischensprache haben, um sie zu manipulieren.
Arrays werden immer als Referenz übergeben (als Speicheradresse) - ein wichtiger Teil des Array-Puzzles, den Sie kennen sollten. Während sie die Grenzen überprüfen (wird einen Fehler auslösen), kann die Grenzprüfung auch für Arrays deaktiviert werden.
Das größte Hindernis für Arrays ist wiederum, dass sie nicht in der Größe veränderbar sind. Sie haben eine "feste" Kapazität. Einführung in ArrayList und List (Of T) in unsere Geschichte:
ArrayList - nicht generische Liste
Die ArrayList (zusammen mit List(Of T)
- obwohl es hier einige kritische Unterschiede gibt, die später erläutert werden) - wird vielleicht am besten als nächste Ergänzung zu Sammlungen angesehen (im weiteren Sinne). ArrayList erbt von der IList-Schnittstelle (ein Nachkomme von 'ICollection'). ArrayLists selbst sind umfangreicher und erfordern mehr Overhead als Lists.
IList
ermöglicht es der Implementierung, ArrayLists als Listen mit fester Größe (wie Arrays) zu behandeln; Abgesehen von der zusätzlichen Funktionalität, die durch ArrayLists hinzugefügt wird, bietet die Verwendung von ArrayLists mit fester Größe keine wirklichen Vorteile, da ArrayLists (gegenüber Arrays) in diesem Fall deutlich langsamer sind.
Nach meiner Lektüre können ArrayLists nicht gezackt werden: "Die Verwendung mehrdimensionaler Arrays als Elemente ... wird nicht unterstützt". Wieder ein weiterer Nagel im Sarg von ArrayLists. ArrayLists werden auch nicht "getippt" - was bedeutet, dass eine ArrayList unter allem einfach ein dynamisches Array von Objekten ist : Object[]
. Dies erfordert viel Boxen (implizit) und Unboxing (explizit) bei der Implementierung von ArrayLists, was wiederum den Overhead erhöht.
Unbegründeter Gedanke: Ich denke, ich erinnere mich, dass ich von einem meiner Professoren gelesen oder gehört habe, dass ArrayLists eine Art Bastard-Konzeptkind für den Versuch sind, von Arrays zu Sammlungen vom Typ Liste zu wechseln, dh einmal eine große Verbesserung für Arrays gewesen zu sein. Sie sind nicht mehr die beste Option, da die Sammlungen weiterentwickelt wurden
Liste (von T): Was ArrayList wurde (und hoffte zu sein)
Der Unterschied in der Speichernutzung ist signifikant genug, um zu erreichen, dass eine Liste (von Int32) 56% weniger Speicher verbraucht als eine ArrayList, die denselben primitiven Typ enthält (8 MB gegenüber 19 MB in der verknüpften Demonstration des oben genannten Gentlemans: wieder hier verknüpft ) Dies ist ein Ergebnis, das von der 64-Bit-Maschine zusammengesetzt wird. Dieser Unterschied zeigt wirklich zwei Dinge: Erstens (1) ist ein "Objekt" vom Typ Int32 (ArrayList) in einer Box viel größer als ein reiner primitiver Int32-Typ (Liste); Zweitens (2) ist der Unterschied aufgrund des Innenlebens einer 64-Bit-Maschine exponentiell.
Also, was ist der Unterschied und was ist eine Liste (von T) ? MSDN definiert a List(Of T)
als "... eine stark typisierte Liste von Objekten, auf die über den Index zugegriffen werden kann." Die Wichtigkeit hierbei ist das "stark typisierte" Bit: Eine Liste (von T) "erkennt" Typen und speichert die Objekte als ihren Typ. Ein Int32
wird also als Int32
und nicht als Object
Typ gespeichert . Dies beseitigt die Probleme, die durch das Ein- und Auspacken verursacht werden.
MSDN gibt an, dass dieser Unterschied nur beim Speichern primitiver Typen und nicht von Referenztypen zum Tragen kommt. Auch der Unterschied tritt wirklich im großen Maßstab auf: über 500 Elemente. Interessanter ist, dass die MSDN-Dokumentation lautet: "Es ist zu Ihrem Vorteil, die typspezifische Implementierung der List (Of T) -Klasse anstelle der ArrayList-Klasse zu verwenden."
Im Wesentlichen ist List (Of T) ArrayList, aber besser. Es ist das "generische Äquivalent" von ArrayList. Wie bei ArrayList kann die Sortierung erst nach dem Sortieren garantiert werden (siehe Abbildung). List (Of T) hat auch einige zusätzliche Funktionen.