Dynamic list, also known as List<T> is a versatile and widely used data structure in programming. Unlike arrays, which have a fixed size, lists can grow and shrink dynamically, making it an ideal choice for situations where you need to manage collections of items without knowing the exact number of elements in advance. It allows for direct access to elements through an index, much like an array, offering a blend of flexibility and efficiency.
Lists are generic data types, and because of that, a list can hold any type of element, from numbers and text, to more complex objects, like instances of custom classes. Here is a quick example of how you can use lists:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// creaza o lista de date de tip primitiv, precum string-ul
List<string> listaaStringuri = new List<string>();
// adauga cateva elemente
listaaStringuri.Add("pisica");
listaaStringuri.Add("caine";);
listaaStringuri.Add("om";);
// creaza o lista de tipuri mai complexe, precum o clasa
List<Elev> listaaClase = new List<Elev>();
// adauga o noua instanta a clasei, ca element al listei
listaaClase.Add(new Elev() { Prenume = "Ion", Nume = "Popescu", Varsta = 18 });
// acceseaza o variabila a clasei din lista
int age = listaaClase[0].Varsta;
Console.ReadLine();
}
}
class
Elev
{
public string Nume { get; set; }
public string Prenume { get; set; }
public int Varsta { get; set; }
}
}
|
Unul din avantajele cheie ale folosirii listei este abilitatea sa de a-și ajusta în mod dinamic mărimea. Când adăugați elemente într-o listă, se extinde în mod automat pentru a acomoda noile elemente. Asta înseamnă că nu e necesar să specificați din start mărimea listei, așa cum sunteți obligați în cazul array-urilor, însă rețineți abilitatea foarte utilă de a accesa elemente prin indexul lor (așa cum faceți în cazul array-urilor), spre deosebire de lista înlănțuită, while also being generic, unlike array lists. So, really, lists are one of the most used data structures because they really are best of all worlds: they eliminate the rigidity of array fixed sizes, eliminate the downside of linked lists not being able to access any element by index at will, and still keep the key feature of being strongly typed generic, and all this while still maintaining a very good performance.
One thing to notice about the List is the fact that once you declare it of a certain type, you cannot add any other types to it. In other words, if you declare a list of type string, you can only add string variables to it, and no other type.
Additional Information
Lists contain internally a normal array. The way lists deal with an unknown number of elements is by doubling the size of their internal array each time it's about to get filled. This means that lists can get to store a lot of items in very few performance steps, thorugh these doublings of their internal container. Even better, lists have an overload constructor where you can specify an int representing the starting size of their internal array, such that they start with the desired number of elements from the beginning.
Adding elements is generally fast, except the times when the internal array must expand to accommodate more elements. This resizing process, although rare, takes more time than simply adding an element to an existing space. However, this impact is mitigated by the fact that such expansions happen infrequently, and over many additions, the time taken per operation averages out to be relatively quick, a concept known as amortized complexity.
Searching for an element or removing elements (by index or value) involves going through the list, making these operations linear in time complexity; they take longer as the list grows.
The most important methods of lists are:
Add(), AddRange() - appends a new element (respectively, a collection of elements) to the end. We can keep adding elements to the collection until memory runs out. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// creaza o lista de string-uri
List<string> lista = new List<string>();
// foloseste metoda Add pentru a adauga elemente
lista.Add("pisica");
lista.Add("caine";);
lista.Add("om";);
// printeaza elementele listei
Console.WriteLine("Valori initiale:");
foreach (string valoare in lista);
Console.WriteLine(valoare);
Console.WriteLine();
// declara o alta colectie de elemente
string[] array = new string[2];
array[0] = "cow";
array[1] = "bird";
// foloseste metoda AddRange pentru a adauga o intreaga colectie deodata
lista.AddRange(array);
// itereaza prin lista
Console.WriteLine("Valori finale:");
foreach (string valoare in lista);
Console.WriteLine(valoare);
Console.ReadLine();
}
}
}
|
Notice that AddRange() does not necessarily expect another list, it works with different types of collections too, such as raw arrays. This is the output:
Clear() - clears the elements of a list. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// creaza o lista de booleni
List<bool> lista = new List<bool>();
// adauga cateva elemente
lista.Add(true);
lista.Add(false);
lista.Add(true);
// printeaza numarul de elemente
Console.WriteLine("Numar de elemente " + lista.Count);
Console.WriteLine();
// curata lista
lista.Clear();
// printeaza noul numar de elemente
Console.WriteLine("Numar de elemente dupa Clear: " + lista.Count);
Console.ReadLine();
}
}
}
|
This is the output:
Sort(), Reverse() - sorts a list, or reverses the order of its elements. In case of sorting, for strings it orders them alphabetically; for integers (or other numbers) it orders from lowest to highest. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// creaza o lista de string-uri
List<string> lista = new List<string>();
// adauga cateva elemente
lista.Add("ton");
lista.Add("stiuca");
lista.Add("crap");
// printeaza elementele listei
Console.WriteLine("Valori initiale:");
foreach (string valoare in lista);
Console.WriteLine(valoare);
Console.WriteLine();
// sorteaza pestii in alfabetic, in ordine ascendenta (A - Z)
lista.Sort();
// printeaza elementele dupa sortare
Console.WriteLine("Elemente dupa sortare:");
foreach (string valoare in lista);
Console.WriteLine(valoare);
Console.WriteLine();
// inverseaza ordinea elementelor
lista.Reverse();
// printeaza elementele din nou
Console.WriteLine("Elemente inversate:");
foreach (string valoare in lista);
Console.WriteLine(valoare);
Console.ReadLine();
}
}
}
|
With this result:
Insert(), InsertRange(), Remove(), RemoveAt() - allow adding or removing one element or a collection of elements. With the exception of Remove(), all require a numerical index at which to insert or remove. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// declara o lista
List<int> lista = new List<int>();
// adauga elemente la sfarsit, folosind metoda Add
for (int i = 0; i < 100000; i++)
lista.Add(i); // operatiune rapida
// curata lista
lista.Clear();
// adauga elemente la inceput, folosind metoda Insert
for (int i = 0; i < 100000; i++)
lista.Insert(0, i); // operatiune inceata
// declara un nou array de tip int
int[] array = new int[3];
array[0] = 7;
array[1] = 6;
array[2] = 7;
// insereaza noul array in lista, la pozitia 1
lista.InsertRange(1, array);
// elimina elementul cu valoarea 5 (NU indexul 5!)
lista.Remove(5);
// elimina elementul cu indexul 2
lista.RemoveAt(2);
Console.ReadLine();
}
}
}
|
IndexOf() - searches for the provided element in the list, and returns its index, if found. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// declara o lista
List<int> numerePrime = new List<int>() { 19, 23, 29 };
// cauta un element care exista
int index = numerePrime.IndexOf(23);
Console.WriteLine(index);
// incearca sa iei indexul unui element care nu exista
index = numerePrime.IndexOf(10);
Console.WriteLine(index);
Console.ReadLine();
}
}
}
|
With this result (-1 representing a "non-existing" index):
Insert(), InsertRange(), Remove(), RemoveAt() - allow adding or removing one element or a collection of elements. With the exception of Remove(), all require a numerical index at which to insert or remove. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
using
System;
using
System.Collections.Generic;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// declara o lista
List<int> lista = new List<int>();
// adauga elemente la sfarsit, folosind metoda Add
for (int i = 0; i < 100000; i++)
lista.Add(i); // operatiune rapida
// curata lista
lista.Clear();
// adauga elemente la inceput, folosind metoda Insert
for (int i = 0; i < 100000; i++)
lista.Insert(0, i); // operatiune inceata
// declara un nou array de tip int
int[] array = new int[3];
array[0] = 7;
array[1] = 6;
array[2] = 7;
// insereaza noul array in lista, la pozitia 1
lista.InsertRange(1, array);
// elimina elementul cu valoarea 5 (NU indexul 5!)
lista.Remove(5);
// elimina elementul cu indexul 2
lista.RemoveAt(2);
Console.ReadLine();
}
}
}
|
Contains(), Exists(), Find() - they all provide searching. They vary in arguments accepted. With Predicates, we influence what elements match. We haven't learn about LINQ and predicates, but they are not the scope of this lesson. Return to this lesson when you learn them. Example:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
using
System;
using
System.Collections.Generic;
using
System.Linq;
namespace
BunaLume
{
class
Program
{
static void Main(string[] args)
{
// declara o lista cu trei elemente
List<string> lista = new List<string>();
lista.Add("pisica");
lista.Add("caine";);
lista.Add("MOLIE");
// cauta un element
if (lista.Contains("caine";))
Console.WriteLine("Caine nu a fost gasit");
// cauta un element ignorand capitalizarea
// ... aceasta este metoda LINQ cu acelasi nume
if (lista.Contains("MOLIE", StringComparer.OrdinalIgnoreCase))
Console.WriteLine("MOLIE a fost gasit (insenzitiv)");
// cauta un element care nu exista
Console.WriteLine(lista.Contains("peste"));
// declara o noua lista
List<int> lista2 = new List<int>();
lista2.Add(7);
lista2.Add(11);
lista2.Add(13);
// verifica daca elemente cu valori mai mari de 10 exista
bool exista = lista2.Exists(element => element > 10);
Console.WriteLine(exista);
// verifica pentru numere mai mici de 7
exista = lista2.Exists(element => element < 7);
Console.WriteLine(exista);
// gaseste primul element mai mare de 11
int result = lista2.Find(element => element > 11);
Console.WriteLine(result);
Console.ReadLine();
}
}
}
|
Output:
There are a ton of other methods that lists have, these are just the most used. Be sure to read the in-depth documentation on the Microsoft website, at least in an informative way, before you start writing your own version of ToArray(), for instance.
The most important properties of lists are:
Capacity - the number of elements of the internal array (filled or empty); you can pass an integer to the constructor of the list (which sets an initial capacity) to improve allocation performance
Count - gets the number of elements of the list. Count, on the list type, is equal to Length on arrays.