Delen via


Verzamelingen en gegevensstructuren

Vergelijkbare gegevens kunnen vaak efficiënter worden verwerkt wanneer ze worden opgeslagen en bewerkt als een verzameling. U kunt de System.Array klasse of de klassen in de System.Collections, System.Collections.Genericen System.Collections.ConcurrentSystem.Collections.Immutable naamruimten gebruiken om afzonderlijke elementen of een reeks elementen in een verzameling toe te voegen, te verwijderen en te wijzigen.

Er zijn twee hoofdtypen verzamelingen; algemene verzamelingen en niet-algemene verzamelingen. Algemene verzamelingen zijn typeveilig tijdens het compileren. Daarom bieden algemene verzamelingen doorgaans betere prestaties. Algemene verzamelingen accepteren een typeparameter wanneer ze worden samengesteld. U hoeft niet naar en van het Object type te casten wanneer u items aan de verzameling toevoegt of verwijdert. Daarnaast worden de meeste algemene verzamelingen ondersteund in Windows Store-apps. Niet-algemene verzamelingen slaan items op als Object, vereisen casting en de meeste worden niet ondersteund voor Windows Store-app-ontwikkeling. Mogelijk ziet u echter niet-algemene verzamelingen in oudere code.

In .NET Framework 4 en hoger bieden de verzamelingen in de System.Collections.Concurrent naamruimte efficiënte threadveilige bewerkingen voor toegang tot verzamelingsitems uit meerdere threads. De onveranderbare verzamelingsklassen in de System.Collections.Immutable naamruimte (NuGet-pakket) zijn inherent thread-safe omdat bewerkingen worden uitgevoerd op een kopie van de oorspronkelijke verzameling en de oorspronkelijke verzameling niet kan worden gewijzigd.

Algemene verzamelingsfuncties

Alle verzamelingen bieden methoden voor het toevoegen, verwijderen of zoeken van items in de verzameling. Bovendien delen alle verzamelingen die direct of indirect de ICollection interface of de ICollection<T> interface implementeren de volgende functies.

Daarnaast bevatten veel verzamelingsklassen de volgende functies:

  • Eigenschappen voor capaciteit en aantal

    De capaciteit van een verzameling is het aantal elementen dat deze kan bevatten. Het aantal van een verzameling is het aantal elementen dat deze daadwerkelijk bevat. Sommige verzamelingen verbergen de capaciteit of het aantal of beide.

    De meeste verzamelingen breiden automatisch capaciteit uit wanneer de huidige capaciteit wordt bereikt. Het geheugen is opnieuw toegewezen en de elementen worden gekopieerd van de oude verzameling naar de nieuwe. Dit ontwerp vermindert de code die nodig is voor het gebruik van de verzameling. De prestaties van de verzameling kunnen echter negatief worden beïnvloed. Als het bijvoorbeeld List<T>Count minder is danCapacity, is het toevoegen van een item een O(1)-bewerking. Als de capaciteit moet worden verhoogd om het nieuwe element aan te kunnen, wordt het toevoegen van een item een O(n-bewerking, waar n dat is Count. De beste manier om slechte prestaties te voorkomen die worden veroorzaakt door meerdere herlocaties, is door de initiële capaciteit in te stellen op de geschatte grootte van de verzameling.

    A BitArray is een speciaal geval; de capaciteit is gelijk aan de lengte, die gelijk is aan het aantal.

  • Een consistente ondergrens

    De ondergrens van een verzameling is de index van het eerste element. Alle geïndexeerde verzamelingen in de System.Collections naamruimten hebben een ondergrens van nul, wat betekent dat ze 0-geïndexeerd zijn. Array heeft standaard een ondergrens van nul, maar een andere ondergrens kan worden gedefinieerd bij het maken van een exemplaar van de matrixklasse met behulp van Array.CreateInstance.

  • Synchronisatie voor toegang vanaf meerdere threads (System.Collections alleen klassen).

    Niet-algemene verzamelingstypen in de System.Collections naamruimte bieden enige threadveiligheid met synchronisatie; doorgaans beschikbaar via de SyncRoot en IsSynchronized leden. Deze verzamelingen zijn standaard niet thread-veilig. Als u schaalbare en efficiënte multithread-toegang tot een verzameling nodig hebt, gebruikt u een van de klassen in de System.Collections.Concurrent naamruimte of kunt u overwegen een onveranderbare verzameling te gebruiken. Zie Thread-Safe Verzamelingenvoor meer informatie.

Een verzameling kiezen

Over het algemeen moet u algemene verzamelingen gebruiken. In de volgende tabel worden enkele veelvoorkomende verzamelingsscenario's en de verzamelingsklassen beschreven die u voor deze scenario's kunt gebruiken. Als u geen toegang hebt tot algemene verzamelingen, helpt de volgende tabel u bij het kiezen van de algemene verzameling die het beste werkt voor uw taak:

Ik wil... Algemene verzamelingsopties Niet-algemene verzamelingsopties Opties voor thread-veilige of onveranderbare verzameling
Items opslaan als sleutel-/waardeparen voor snel opzoeken op sleutel Dictionary<TKey,TValue> Hashtable

(Een verzameling sleutel-/waardeparen die zijn geordend op basis van de hashcode van de sleutel.)
ConcurrentDictionary<TKey,TValue>

ReadOnlyDictionary<TKey,TValue>

ImmutableDictionary<TKey,TValue>
Toegang tot items via index List<T> Array

ArrayList
ImmutableList<T>

ImmutableArray
Gebruik items volgens het first-in-first-out (FIFO) principe Queue<T> Queue ConcurrentQueue<T>

ImmutableQueue<T>
De laatste binnengekomen Data gebruiken -First-Out (LIFO) Stack<T> Stack ConcurrentStack<T>

ImmutableStack<T>
Items sequentieel benaderen LinkedList<T> Geen aanbeveling Geen aanbeveling
Meldingen ontvangen wanneer items worden verwijderd of toegevoegd aan de verzameling. (implementeert INotifyPropertyChanged en INotifyCollectionChanged) ObservableCollection<T> Geen aanbeveling Geen aanbeveling
Een gesorteerde verzameling SortedList<TKey,TValue> SortedList ImmutableSortedDictionary<TKey,TValue>

ImmutableSortedSet<T>
Een set voor wiskundige functies HashSet<T>

SortedSet<T>
Geen aanbeveling ImmutableHashSet<T>

ImmutableSortedSet<T>

Algoritmecomplexiteit van verzamelingen

Wanneer u een verzamelingsklasse kiest, is het de moeite waard om mogelijke compromissen in prestaties te overwegen. Gebruik de volgende tabel om te verwijzen naar de vergelijking van verschillende onveranderbare verzamelingstypen in algoritmecomplexiteit met de bijbehorende onveranderbare tegenhangers. Onveranderbare verzamelingstypen zijn vaak minder goed presterend, maar bieden onveranderbaarheid, wat vaak een geldig vergelijkend voordeel is.

Veranderlijk Afgeschreven Slechtste geval Onveranderlijk Complexiteit
Stack<T>.Push O(1) O(n) ImmutableStack<T>.Push O(1)
Queue<T>.Enqueue O(1) O(n) ImmutableQueue<T>.Enqueue O(1)
List<T>.Add O(1) O(n) ImmutableList<T>.Add O(logboek n)
List<T>.Item[Int32] O(1) O(1) ImmutableList<T>.Item[Int32] O(logboek n)
List<T>.Enumerator O(n) O(n) ImmutableList<T>.Enumerator O(n)
HashSet<T>.AddOpzoeken O(1) O(n) ImmutableHashSet<T>.Add O(logboek n)
SortedSet<T>.Add O(logboek n) O(n) ImmutableSortedSet<T>.Add O(logboek n)
Dictionary<T>.Add O(1) O(n) ImmutableDictionary<T>.Add O(logboek n)
Dictionary<T> Opzoeken O(1) O(1) – ofwel strikt O(n) ImmutableDictionary<T> Opzoeken O(logboek n)
SortedDictionary<T>.Add O(logboek n) O(n logboek n) ImmutableSortedDictionary<T>.Add O(logboek n)

Een List<T> kan efficiënt worden geïnventariseerd met behulp van een for lus of een foreach lus. Een ImmutableList<T>, echter, doet een slechte taak binnen een for lus, vanwege de O(log n) tijd voor de indexeerfunctie. Het inventariseren van een ImmutableList<T> met een foreach lus is efficiënt omdat ImmutableList<T> een binaire boom gebruikt om de gegevens op te slaan in plaats van een array zoals List<T> dat doet. Een matrix kan snel worden geïndexeerd, terwijl er een binaire structuur moet worden doorlopen totdat het knooppunt met de gewenste index wordt gevonden.

SortedSet<T> Daarnaast heeft deze dezelfde complexiteit als ImmutableSortedSet<T> omdat ze beide binaire structuren gebruiken. Het belangrijkste verschil is dat ImmutableSortedSet<T> een onveranderbare binaire boom gebruikt. Aangezien ImmutableSortedSet<T> u ook een System.Collections.Immutable.ImmutableSortedSet<T>.Builder klasse biedt die mutatie toestaat, kunt u zowel onveranderbaarheid als prestaties hebben.

Titel Beschrijving
Een verzamelingsklasse selecteren Beschrijft de verschillende verzamelingen en helpt u er een te selecteren voor uw scenario.
Veelgebruikte verzamelingstypen Beschrijft veelgebruikte algemene en niet-algemene verzamelingstypen zoals System.Array, System.Collections.Generic.List<T>en System.Collections.Generic.Dictionary<TKey,TValue>.
Wanneer algemene verzamelingen gebruiken Hiermee wordt het gebruik van algemene verzamelingstypen besproken.
Vergelijkingen en sorteringen binnen verzamelingen Bespreekt het gebruik van gelijkheidsvergelijkingen en sorteringsvergelijkingen in verzamelingen.
Gesorteerde verzamelingstypen Beschrijft de prestaties en kenmerken van gesorteerde verzamelingen.
Hashtabel- en Woordenlijstverzamelingstypen Beschrijft de functies van algemene en niet-algemene hash-woordenlijsttypen.
Thread-Safe Verzamelingen Beschrijft verzamelingstypen zoals System.Collections.Concurrent.BlockingCollection<T> en System.Collections.Concurrent.ConcurrentBag<T> die veilige en efficiënte gelijktijdige toegang vanuit meerdere threads ondersteunen.
System.Collections.Immutable Introduceert de onveranderbare verzamelingen en biedt koppelingen naar de verzamelingstypen.

Referentie