Een groot nadeel van een List bestaat erin dat je elementen van verschillende datatypes kán opslaan:
List mijnLijst=newList();
mijnLijst.Add(1);
mijnLijst.Add("Twee");
mijnLijst.Add(true);
mijnLijst.Add(100.45);
mijnLijst.Add(DateTime.Now);
Hierdoor moet je zelf controleren of de elementen die je uit de List haalt wel van het type zijn dat je verwacht. We moetenaan typecasting gaan doen, anders geeft ons programma een RunTime-fout…
//declaratie van een List
List mijnLijst = new List() { 1, "Twee", true, 100.45, DateTime.Now };
//voorbeeld typecasting
int getal = (int)mijnLijst[0];
Gelukkig bestaan er ook generic collections. Deze zijn type-safe, wat betekent dat ze alleen elementen van hetzelfde type kunnen bevatten. Dit betekent dat je geen typecasting meer moet doen om de elementen uit de collection te halen.
De generic collections zijn de volgende:
In deze cursus zullen we enkel de List gebruiken.
INFO
De methoden die je kan gebruiken op een List zijn dezelfde als die je kan gebruiken op een ArrayList. De enige verschillen zijn dat je geen typecasting moet doen en dat je de elementen van een List enkel van hetzelfde type kan bevatten.
Deze werkt als een array maar kan dynamisch groeien. Je hoeft dus bij het declareren van de List niet op voorhand te weten hoeveel elementen er in de List zullen zitten.
Een List declareer je als volgt:
//declaratie van een List
List<int> mijnLijst = new List<int>();
Je ziet dat we achter het DataType List
een <int>
hebben gezet. Dit betekent dat de List nu enkel elementen van het type int
kan bevatten. Als je nu een ander datatype probeert toe te voegen aan de List, krijg je een compilerfout.
//declaratie van een List
List<int> mijnLijst = new List<int>();
//voeg een element van het type string toe aan de List
mijnLijst.Add("Twee");
Wil je een ander datatype gebruiken in de List dan hoef je enkel het <int>
te vervangen door het gewenste datatype.
//declaratie van een List
List<string> mijnLijst = new List<string>();
//voeg een element van het type string toe aan de List
mijnLijst.Add("Twee");
TIP
Voor je een List kan declareren moet je de namespace
System.Collections
importeren. Dit doe je door bovenaan je code een using-instructie te schrijven:using System.Collections;
Je kan eenList ook declareren en initialiseren in één enkele regel code:
//declaratie en initialisatie van een List
List<int> mijnLijst = new List<int>() { 1, 2, 3 };
DezeList bevat nu 3 elementen: 1, 2 en 3
.
Je kan elementen toevoegen aan een List met de methode Add()
. Deze worden dan achteraan de List toegevoegd.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//toevoegen van het element "element 4" aan de List
mijnLijst.Add("element 4");
Deze List bevat nu 4 elementen: "element 1", "element 2", "element 3" en "element 4"
.
Je kan ook elementen toevoegen op een bepaalde plaats in de List. Dit doe je met de methode Insert()
. Deze methode heeft 2 parameters: de index waar je het element wil toevoegen en het element zelf.
Net zoals bij een array, begint de index bij 0.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//toevoegen van het element "element 4" op index 1 in de List
mijnLijst.Insert(1, "element 4");
Bovenstaande code voegt het element “element 4” toe op plaats 1 in de List. De List bevat nu 4 elementen: "element 1", "element 4", "element 2" en "element 3".
Weet je waarom “element 4” op de tweede plaats in de List staat? En niet op de eerste plaats?
Je kan elementen verwijderen uit een List met de methode Remove()
. Deze methode verwijdert het eerste element dat overeenkomt met het meegegeven element.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//verwijderen van het element "element 2"
mijnLijst.Remove("element 2");
De List bevat nu 2 elementen: "element 1" en "element 3"
.
Je kan ook een element verwijderen op basis van zijn index. Dit doe je met de methode RemoveAt()
. Deze methode verwijdert het element op de meegegeven index.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//verwijderen van het element op index 2
mijnLijst.RemoveAt(2);
De List bevat nu 2 elementen: "element 1" en "element 2"
.
Je kan elementen ophalen uit een List op basis van hun index. Dit doe je door de index tussen vierkante haken[] te plaatsen achter de List.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//ophalen van het element op index 1
string element = mijnLijst[1];
//weergeven van het element
Console.WriteLine(element);
Deze code zal het volgende weergeven:
element 2
Je kan het aantal elementen in een List opvragen met de methode Count
.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//ophalen van het aantal elementen in de List
int aantalElementen = mijnLijst.Count;
//weergeven van het aantal elementen
Console.WriteLine(aantalElementen);
Deze code zal het volgende weergeven:
3
Er zijn twee manieren om alle elementen in een List te weergeven:
Je kan een for-loop gebruiken om alle elementen in een List te weergeven. De for-loop loopt door alle elementen in de List en weergeeft ze.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//weergeven van alle elementen in de List
for (int i = 0; i < mijnLijst.Count; i++){
Console.WriteLine(mijnLijst[i]);
}
Deze code zal het volgende weergeven:
element 1
element 2
element 3
De foreach-lus is nieuw voor jullie. Deze is speciaal ontworpen om door een collectie te loopen. De foreach-lus is een verkorte versie van de For-lus. De foreach-lus is dus een makkelijkere manier om door een collectie te loopen.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//weergeven van alle elementen in de List
foreach (string element in mijnLijst){
//binnen deze lus wordt bij elke iteratie het volgende element uit de List
// opgehaald en in de variabele element gestoken
Console.WriteLine(element);
}
Deze code zal het volgende weergeven:
element 1
element 2
element 3
Zoals je ziet kunnen we in de foreach-loop de variabele element
van het type string
declareren. Dit is omdat we weten dat de List van het type string
is. Als we dit niet zouden doen, dan zou de compiler een foutmelding geven. Dit allemaal omdat de List een generieke collectie is en dus type-safe is.
De List heeft nog een aantal andere methodes die je kan gebruiken. Een overzicht van de methodes vind je hier7. Enkele veelgebruikte methodes zijn:
De Contains()
-methode controleert of een element in de List aanwezig is. Deze methode geeft een bool
terug. Als het element aanwezig is, geeft de methode true
terug. Als het element niet aanwezig is, geeft de methode false
terug.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//controle of het element "element 2" aanwezig is in de List
bool aanwezig = mijnLijst.Contains("element 2");
//indien het element aanwezig is, wordt toon "element 2 is aanwezig" weergegeven
if (aanwezig){
Console.WriteLine("element 2 is aanwezig");
}else{
Console.WriteLine("element 2 is niet aanwezig");
}
De Sort()
-methode sorteert de elementen in de List. De elementen worden gesorteerd op basis van hun natuurlijke orde. Dit betekent dat de elementen gesorteerd worden op basis van hun type. Zo worden int
-elementen gesorteerd van klein naar groot, string
-elementen worden gesorteerd op alfabetische volgorde, enzovoort.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 3", "element 1", "element 2" };
//sorteren van de List
mijnLijst.Sort();
//weergeven van de gesorteerde List
foreach (var element in mijnLijst){
Console.WriteLine(element);
}
Deze code zal het volgende weergeven:
element 1
element 2
element 3
De Reverse()
-methode keert de volgorde van de elementen in de List om.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//omkeren van de volgorde van de elementen in de List
mijnLijst.Reverse();
//weergeven van de omgekeerde List
foreach (var element in mijnLijst){
Console.WriteLine(element);
}
Deze code zal het volgende weergeven:
element 3
element 2
element 1
De IndexOf()
-methode geeft de index van een element in de List terug. Als het element niet in de List aanwezig is, geeft de methode -1
terug.
//declaratie en initialisatie van een List
List<string> mijnLijst = new List<string>() { "element 1", "element 2", "element 3" };
//opvragen van de index van het element "element 2"
int index = mijnLijst.IndexOf("element 2");
//weergeven van de index van het element
Console.WriteLine(index);
Deze code zal het volgende weergeven:
1
Ze zijn ook niet performant, wat betekent dat ze niet zo efficiënt zijn als de generic collections. Ze zijn echter wel eenvoudig in gebruik.
Het is zinloos om deze antwoorden te bekijken als je niet zelf intensief hebt geprobeerd de opgaves op te lossen. Je kunt alleen programmeren leren door het te doen. Gebruik deze antwoorden alleen om ze te vergelijken met je eigen oplossingen, of als een laatste redmiddel als je geen idee hebt over hoe je een probleem moet aanpakken. Maar als je een probleem niet kunt oplossen, is het meestal beter om er een eerder deel van de cursus8 op na te slaan om informatie op te zoeken die je niet hebt begrepen of vergeten bent.
Vaak zijn de antwoorden die ik geef slechts één van vele mogelijkheden om een opgave op te lossen. Als jij een andere manier hebt gevonden, kan dat best correct zijn, maar zorg ervoor dat je je oplossingen uitgebreid test om er zeker van te zijn dat ze correct zijn.
Bedenk dat, hoewel de antwoorden die ik geef meestal efficiënt zijn, efficiëntie niet een hoofddoel is wanneer je code schrijft. Je hoofddoel is om code te schrijven die een probleem oplost, en pas als dat gelukt is, moet je overwegen of de oplossing efficiënter gemaakt kan worden. Leesbaarheid en onderhoudbaarheid zijn veel belangrijker dan efficiëntie.19
Ik wil de volgende punten expliciet onder de aandacht brengen:
Je moet aan de opgaves werken totdat je ze opgelost hebt. Het volstaat niet om een beetje te proberen en dan het antwoord op te zoeken. Een dergelijke aanpak is volstrekt zinloos. Je zult nooit leren programmeren als je niet nadenkt over oplossingsmethodieken, code schrijft, en code test. Als je een opgave niet kunt oplossen zelfs als je er lange tijd aan hebt gewerkt, doe je er beter aan hulp te vragen dan het antwoord op te zoeken. Het niet kunnen oplossen van een opgave betekent dat er iets in het materiaal zit dat je nog niet begrijpt, en het is belangrijk dat je ontdekt wat dat is, zodat je dat gebrek kunt verhelpen.
Je moet alle opgaves maken. De enige manier om te leren programmeren is te oefenen. Je zult veel code moeten schrijven om de praktijk van het programmeren te internaliseren. De paar opgaves die ik aan het einde van ieder hoofdstuk op heb genomen zijn nog niet voldoende om dat te bereiken, maar ze zijn een begin. Als je niet de moeite neemt om al die opgaves te doen, hoef je ook niet de moeite te doen om te proberen programmeren te leren.
Je moet de opgaves zelfstandig maken. Aan de opgaves werken in groepsverband laat één persoon leren terwijl de rest erbij zit en toekijkt. Studenten vertellen me vaak dat ze een leermethode hebben waarbij ze aan opdrachten werken in groepsverband en antwoorden bediscussiëren. Dat werkt misschien voor het analyseren van teksten en het opzetten van experimenten, maar werkt meestal niet voor coderen. Toekijken hoe iemand anders code schrijft leert je erg weinig over het schrijven van code. Je moet zelf code schrijven.
Als je een opgave hebt opgelost en je je oplossing goed getest hebt, kun je je oplossing vergelijken met het antwoord dat ik geef. Je zult vaak zien dat mijn antwoord anders is dan het jouwe. Dat betekent niet dat jouw antwoord fout is! Er zijn meestal veel verschillende manieren om een programmeerprobleem op te lossen. Sommige zijn “beter” in bepaalde opzichten dan andere. Vele zijn “precies even goed.” Wat van belang is dat je een probleem kunt oplossen door code te schrijven, niet dat je een probleem kunt oplossen door de meest efficiënte code te schrijven. Het volstaat om het probleem op te lossen; oplossingen efficiënt maken is van veel minder belang. Bijvoorbeeld, “efficiëntie” is minder belangrijk dan “begrijpbaarheid” en “onderhoudbaarheid.”
De Programmeursleerling10 - Pieter Spronck ↩11