Cuprins >> Structuri De Date > Lista
Articol de importanță mare

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:

Initial values:
cat
dog
man
 
Final values:
cat
dog
man
cow
bird
 
 

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:

Numar de elemente 3
 
Numar de elemente dupa Clear: 0
 
 

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:

Initial values:
tuna
velvetfish
angler
 
Elemente dupa sortare:
angler
tuna
velvetfish
 
Elemente inversate:
velvetfish
tuna
angler
 
 

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):

1
-1
 
 

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:

Caine nu a fost gasit
MOLIE a fost gasit (insenzitiv)
False
True
False
13
 
 

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.