Cours VB.NETDate de mise à jour : 05/12/2010
V-H. Les 'Tableaux'
V-H-1. Un tableau est un objet de type Array
V-H-2. Fonction avancées sur les tableaux
V-H-3. Exemple courant d'utilisation des tableaux
V-I. Les 'Collections'
V-I-1. Exemple simpliste
V-I-2. Classification des collections
V-I-3. ArrayList
V-I-4. List (Of)
V-I-5. HashTable
V-I-6. Dictionnary (Of)
V-I-7. SortedList SortedList (Of)et SortedSet
V-I-8. Queue
V-I-9. Stack
V-I-10. Les LinkedList (Of)
V-I-11. HashSet (Of)
V-I-12. BitArray
V-I-13. StringCollection
V-I-14. ObservableCollections, SortedSet(Of T)
V-I-15. Généralisation de la notion de collection
V-I-16. Pourquoi le premier élément est-il 0 ou 1 ?
V-I-17. Exemples sur les collections
V-I-18. Lexique anglais=>Français
V-J. Les 'Structures'
V-J-1. Tableau dans une structure
V-J-2. Allons plus loin
V-J-2-a. Les structures sont des types 'valeur'
V-J-2-b. Les structures peuvent contenir plein de choses
V-J-2-c. Portée
V-H. Les 'Tableaux'
C'est un beau tableau, mais en VB, ce n'est pas ça un tableau!!
Les tableaux permettent de regrouper des données de même type.
Les tableaux vous permettent de faire référence à un ensemble de variables par le même nom et d'utiliser un numéro, appelé index ou indice, pour les distinguer.
Comment déclarer un tableau :
Dim Tableau (3) As Integer
|
déclare un tableau de 4 entiers
On remarque que, dés la déclaration du tableau, le nombre d'éléments est bien défini et restera toujours le même. Après As on indique le type utilisé dans le tableau.
Dim Tableau(3) As Integer entraîne la création des variables 'Integer' suivante:
Tableau (0)
Tableau (1)
Tableau (2)
Tableau (3)
Contenu du tableau:
soit 4 éléments.
Noter que comme c'est un tableau d'entier, juste après la création du tableau les éléments sont initialisés à 0.
 |
Le tableau commence toujours par l'indice 0.
Le nombre d'éléments dans le tableau est toujours égale à l'indice de dimension + 1 (ou l'indice du dernier élément+1)
|
Dim Tableau(3) comporte 4 éléments (éléments d'index 0 à 3).
Si j'exécute Tableau(4)=5, cela plante et me donne le message d'erreur suivant:
L'exception System.IndexOutOfRangeException n'a pas été gérée
"L'index se trouve en dehors des limites du tableau."
En effet l'élément Tableau (4) n'existe pas (Le tableau comporte 4 éléments, éléments d'index 0 à 3); l'index 4 est trop grand.
On fait parfois cette erreur quand on utilise une variable comme index dans une boucle par exemple et qu'on a mal calculé la valeur maximun de l'index de boucle.
permet d'affecter le nombre 12 au 2eme élément du tableau.
Dim S As Integer
S= Tableau (1)
|
permet d'affecter à la variable S le 2eme élément du tableau:
Un tableau peut avoir plusieurs dimensions :
Pour un tableau à 2 dimensions le premier argument représente les lignes, le second les colonnes.
Voyons pour chaque élément du tableau le numéro de ligne et celui de la colonne: (pas le contenu des éléments ici mais leurs index)
élément:0,0 |
élément:0,1 |
élément:0,2 |
élément:1,0 |
élément:1,1 |
élément:1,2 |
élément:2,0 |
élément:2,1 |
élément:2,2 |
Exemple:
La première ligne comporte les 3 éléments: T(0,0) T(0,1) et T(0,2)
Pour mettre 33 dans l'élément central:
Dim T (2,2) As Integer
T (1,1)= 33
|
voyons le contenu du tableau:
Il est possible de créer des tableaux à 3, 4 ..dimensions:
Exemple:
crée un tableau de 4X2X3 éléments.
On peut créer des tableaux de tableaux:
Il a autant d'élément que le tableau T (2,2) (mais pour l'accès à un élément, ils fonctionnent plus vite).
Il est possible de créer des tableaux avec tous les types de variable (y compris les structures).
Notez que dans ce cas (après la ligne Dim )les éléments contiennent Nothing car le tableau contient des String et quand on déclare une String, elle contient Nothing au départ.
On peut initialiser un tableau (Donner une valeur aux éléments):
En effet après déclaration d'un tableau, il contient:
-la valeur 0 si c'est un tableau de numérique.
-Nothing si c'est un tableau de String ou d'Objet.
Dim mois (11) As String
mois (0)= " Janvier "
mois (1)= " Février "
mois (2)= " Mars "
|
On peut aussi l'initialiser lors de sa déclaration :
Dim Mois () As String = {Janvier,Février,Mars}
Dim winterMonths = {" December " , " January " , " February " }
Dim numbers = {1, 2, 3, 4, 5}
Dim b = {1, 2, 3. 5 }
Dim d = {1, " 123 " }
Dim e = {{1, 2, 3}, {4, 5, 6}}
Dim f = {({1, 2, 3}), ({4, 5, 6})}
|
On remarque ici, que le nombre d'éléments n'est pas indiqué; comme on initialise 3 éléments, le tableau en aura 3.
On peut même se passer d'indiquer le type (à partir du deuxième exemple), le compilateur déduit le type à partir des littéraux. On nomme cela l'inférence de type.
A part quand on utilise Linq, je pense qu'il faut mieux indiquer explicitement le type de variable.
Autre syntaxe:
Dim t As String ()
t = New String (1) {" One " , " Two " }
Dim R (,) as Integer = {{0, 1}, {1, 2}, {0, 0}, {2, 3}}
|
Dans le premier exemple, on fait les choses en deux étapes, on déclare puis on dimensionne (instanciation) et on initialise un tableau 't'.
Dans le second exemple, n déclare et on initialise en même temps un tableau à 2 dimensions, remarquez qu'on rentre les éléments 2 à 2.(Equivalent à R(0,0)=0 R(0,1)=1 R(1,0)=1 R(1,1)=2 ..)
Redim permet de redimensionner un tableau (modifier le nombre d'éléments d'un tableau existant), si on ajoute Preserve les anciennes valeurs seront conservées (Array.Resize fait de même, voir plus bas).
 |
Attention, on ne peut pas modifier le nombre de dimension, ni le type des données. Un tableau à 2 dimensions de 20 fois 20 string pourra être redimensionné en tableau de 30 fois 30 String, mais pas en tableau d'entiers ou à 3 dimensions.
|
Dim T (20,20) As String
. . .
Redim Preserve T (30,30)
|
Il est possible d'écrire Dim T( , ) As String
Dim T( , ) As String 'Sans donner les dimensions du tableau: il est déclaré mais n'existe pas car T(1,1)="toto" déclenche une erreur. Il faut avant de l'utiliser écrire Redim T(30,30), (sans remettre As String).
Certaines instructions, comme Split (qui découpe une String pour la mettre dans un tableau), redimensionnent elles-même le tableau au nombre d'élément nécessaire.
Dim Nom () as String
Nom= S. Split (Separateur)
|
Erase efface le tableau et récupère l'espace.
Erase Tableau (équivalent à tableau= Nothing ).
Clear réinitialise le tableau (remise à 0 d'un tableau de numérique par exemple).
Réinitialisation tableau t à partir de l'élément 1 et pour 3 éléments.
Comment parcourir un tableau?
Pour parcourir un à un tous les éléments d'un tableau, on utilise une boucle:
Exemple: créer un tableau de 11 éléments et mettre 0 dans le premier élément, 1 dans le second, 2 dans le troisième...
Dim T (10) As Integer
Dim i As Integer
For i = 0 To 10
T (i)= i
Next i
|
La variable de boucle i est utilisée pour parcourir le tableau: on utilise l'élément T( i ) donc successivement T(1) puis T(2)...et on affecte i donc 1 puis 2 puis 3..
On peut aussi utiliser For Each:( un tableau hérite de la classe System.Array)
Dim amis () As String = {" pierre " , " jean " , " jacques " , " toto " }
For Each nom As String In amis
Console. Out . WriteLine (nom)
Next
|
L'exemple affiche sur la console (menu Affichage->Fenêtre->Sortie) les noms qui sont dans le tableau.
VB alloue de l'espace mémoire pour chaque élément crée. Ne dimensionnez pas un immense tableau si vous avez besoin d'un tableau de 4*4 car cela utilise de la mémoire inutilement.
V-H-1. Un tableau est un objet de type Array
La Classe Array (tableau) a des propriétés et des méthodes que l'on peut utiliser.
Créons 2 tableaux et examinons les principales méthodes.
Dim a (3) As String
Dim b (3) As String
b= a
b= a. copy
|
 |
Attention: il copie les références (l'adresse, l'endroit ou se trouve la variable) et non pas la valeur de cette variable, ce qui fait que si vous modifiez b(3), a(3) sera aussi modifié.
|
Car lorsque vous assignez une variable tableau à une autre, seul le pointeur (l'adresse en mémoire) est copié. Donc en fait a et b sont le même tableau.
Pour obtenir une copie 'indépendante' dans un nouveau tableau faire :
Dans ce cas si vous modifié a(2), b(2) ne sera pas modifié.
Par contre a(1)=b(1) n'affecte que l'élément a(1).
Soit un tableau Mois()
Clear
Array.Clear(Mois,0,2) Efface 2 éléments du tableau Mois à partir de l'élément 0.
Reverse
Array.Reverse(Mois, 1, 3) inverse les 3 éléments à partir de l'élément 1.
Copy
Array.Copy(Mois,1,Mois2,1,20) copie 20 éléments de Mois vers Mois2 à partir du 2eme élément.
Array.ConstrainedCopy fait la même chose mais annule tous si la copie n'est pas effectuée intégralement.
De même: mySourceArray.CopyTo(myTargetArray, 6) copie TOUS les éléments de la source dans la destination à partir d'un index dans la destination.
Sort
Array.sort(Mois) Trie le tableau Mois
Malheureusement cette méthode marche sur des tableaux unidimensionnels uniquement.
Au lieu d'utiliser un tableau à 2 dimensions (sur lequel la méthode 'Sort' ne marche pas, on peut ruser et créer 2 tableaux et surcharger la méthode sort pour trier les 2 tableaux (un servant de clé, le second d'items):
Array.Sort(myKeys, myValues) (Voir un exemple plus bas).
Equals compare 2 tableaux.
Binarysearch recherche un élément dans un tableau trié unidimensionnel.(algorithme de comparaison binaire performant sur tableau trié)
Exemple :
I= Array . BinarySearch (Mois, " Février " )
|
BinarySearch effectue une recherche dichotomique: il regarde l'élément du milieu, si l'élément cherché est plus petit, il regarde l'élément du milieu du haut du tableau.....
C'est rapide mais le tableau doit être trié.
S'il trouve un élément il retourne son index.
Si la recherche échoue, il retourne un nombre négatif, si on effectue un Not sur ce nombre retourné, on a l'index où on doit insérer l'élément.
IndexOf
Recherche un objet spécifié dans un tableau unidimensionnel (trié ou non), retourne l'index de la première occurrence.
Dim myIndex As Integer = Array . IndexOf (myArray, myString)
|
Retourne -1 si l'élément n'est pas trouvé.
LastIndexOf fait une recherche à partir de la fin.
Ici la recherche est linéaire: on compare l'élément recherché avec le premier puis le deuxième, puis le troisième élément...C'est long , mais le tableau n'a pas besoin d'être trié.
On a probablement intérêt à trier le tableau et à faire un Binarrysearch (Cela se dit mais je ne l'ai pas vérifié);
Ubound
Retourne le plus grand indice disponible pour la dimension indiquée d'un tableau.
Dim Indice, MonTableau (10, 15, 20)
Indice = UBound (MonTableau, 1)
|
GetUpperBound même fonction.
Indice = MonTableau. GetUpperBound (0)
|
Lbound existe (plus petit indice) mais est inutile car toujours égal à 0.
Length retourne un entier qui représente le nombre d'éléments total dans le tableau.
Pour un tableau à une dimension Length-1 retourne l'indice du dernier élément.
Cela est souvent utilisé pour parcourir tous les éléments du tableau:
Dim t (10) As String
Dim i As Integer
For i = 0 To t. Length - 1
t (i)= . .
Next t
|
On remarque que dans un tableau multi dimension Length n'est pas égale à Ubound.
GetLength(x) retourne un entier qui représente le nombre d'éléments dans la dimension x.
GetValue et SetValue permettent de connaître ou de modifier la valeur d'un élément du tableau:
Mois.GetValue(0) est équivalent à Mois(0)
Dans un tableau à 2 dimensions comment modifier l'élément (0,3):
myArray. SetValue (" fox " , 0, 3)
|
C'est équivalent à myArray(0,3)="fox"
ArraySegment permet de définir un segment, une plage dans une Array.(framework 2).
Dim myArrSegMid As New ArraySegment (Of String )(myArray, 2, 5)
|
(Si on modifie un élément de myArrSegMid cela modifie myArray car le segment défini une plage du tableau et non un nouveau tableau)
Sur des tableaux, les actions à effectuer sont principalement:
Rechercher un élément.
Trier le tableau.
Insérer un élément.
Enlever un élément.
On a déjà évoqué cela, mais pour étudier le détail de ces algorithmes voir le chapitre 'Travail sur les tableaux et collections'.
Pour les super pro (débutant passe ton chemin), on peut utiliser des méthodes génériques.
Exemple recherche dans un tableau de Short nommé monTab l'élément 2.
index= Array.indexOf (Of Short)(monTab, 2) est hyper plus rapide que
index= Array.indexOf (monTab, 2) car la première version avec généric est directement optimisée pour les Short.
Il est est de même pour Binarysearch et Sort.
Cela est valable pour les types 'valeur' (peu d'intérêts pour les strings par exemple).
V-H-2. Fonction avancées sur les tableaux
Débutant s'abstenir:
La méthode Resize permet de modifier le nombre d'éléments du tableau sans perdre le contenu:
Dim array As T (10)
Dim newSize As Integer= 2
Array . Resize (array , newSize)
|
La méthode Reverse permet d'inverser les éléments d'un tableau.
Dim t (10) As Integer
t (1) = 2
Array . Reverse (t)
|
On peut aussi spécifier l'indice de début et le nombre d'éléments à inverser.
Dim t (10) As Integer
t (1) = 2
Array . Reverse (t, 2, 2)
|
A partir du Framework 2 les Arrays ont donc de nouvelles méthodes:
- Exists
- Le tableau contient-il des éléments qui correspondent aux conditions définies par un prédicat?
- TrueForAll
- Chaque élément dans le tableau correspond-il aux conditions définies par un prédicat?
- Find
- Recherche un élément qui correspond aux conditions définies par le prédicat et retourne la première occurrence.
- FindLast
- Idem pour la derniere occurrence.
- FindAll
- Récupère tous les éléments qui correspondent aux conditions définies par le prédicat.
- ConvertAll
- Chaque élément est passé individuellement à un Converter, et les éléments convertis sont enregistrés dans le nouveau tableau.
La syntaxe est dela forme Array.Find(Tableau, AdresseOf Predicat)
Un Predicat est une Sub qui retourne True si une condition est remplie.
Exemple fournit par Microsoft: On a un tableau contenant le nom d'animaux préhistoriques, le prédicat retourne True si le nom de l'animal se termine par 'saurus'. On veut savoir si la condition est remplie sur la liste au moins une fois (Exists), si tous les éléments remplissent la condition (TrueForAll),
quel élément rempli la condition(Find), le premier, le dernier (FindLast), on veut récupérer dans un nouveau tableau tous les éléments qui remplissent la condition.
Dim dinosaurs () As String = { " Compsognathus " , _
" Amargasaurus " , " Oviraptor " , " Velociraptor " , _
" Deinonychus " , " Dilophosaurus " , " Gallimimus " , _
" Triceratops " }
Console. WriteLine ()
For Each dinosaur As String In dinosaurs
Console. WriteLine (dinosaur)
Next
Console. WriteLine (vbLf & _
" Array.Exists(dinosaurs, AddressOf EndsWithSaurus): {0} " , _
Array . Exists (dinosaurs, AddressOf EndsWithSaurus))
Console. WriteLine (vbLf & _
" Array.TrueForAll(dinosaurs, AddressOf EndsWithSaurus: {0} " , _
Array . TrueForAll (dinosaurs, AddressOf EndsWithSaurus))
Console. WriteLine (vbLf & _
" Array.Find(dinosaurs, AddressOf EndsWithSaurus): {0} " , _
Array . Find (dinosaurs, AddressOf EndsWithSaurus))
Console. WriteLine (vbLf & _
" Array.FindLast(dinosaurs, AddressOf EndsWithSaurus): {0} " , _
Array . FindLast (dinosaurs, AddressOf EndsWithSaurus))
Console. WriteLine (vbLf & _
" Array.FindAll(dinosaurs, AddressOf EndsWithSaurus): " )
Dim subArray () As String = _
Array . FindAll (dinosaurs, AddressOf EndsWithSaurus)
For Each dinosaur As String In subArray
Console. WriteLine (dinosaur)
Next
End Sub
Private Shared Function EndsWithSaurus (ByVal s As String ) _
As Boolean
If (s. Length > 5) AndAlso _
(s. Substring (s. Length - 6). ToLower () = " saurus " ) Then
Return True
Else
Return False
End If
End Function
|
Résultat affiché:
'Compsognathus
'Amargasaurus
'Oviraptor
'Velociraptor
'Deinonychus
'Dilophosaurus
'Gallimimus
'Triceratops
'
'Array.Exists(dinosaurs, AddressOf EndsWithSaurus): True
'
'Array.TrueForAll(dinosaurs, AddressOf EndsWithSaurus: False
'
'Array.Find(dinosaurs, AddressOf EndsWithSaurus): Amargasaurus
'
'Array.FindLast(dinosaurs, AddressOf EndsWithSaurus): Dilophosaurus
'
'Array.FindAll(dinosaurs, AddressOf EndsWithSaurus):
'Amargasaurus
'Dilophosaurus
|
Pour Array.ConvertAll, elle retourne un tableau dont chaque élément qui vient d'un premier tableau a été modifié par une fonction:
Ici on va créer une fonction qui mettre en majuscules.
Private Sub Button1_Click () Handles Button1. Click
Dim dinosaurs () As String = {" Compsognathus " , _
" Amargasaurus " , " Oviraptor " , " Velociraptor " , _
" Deinonychus " , " Dilophosaurus " , " Gallimimus " , _
" Triceratops " }
Dim dinosaurs2 () As String
dinosaurs2 = Array . ConvertAll (dinosaurs, New Converter (Of String , String )(AddressOf MettreEnMajuscules))
End Sub
Private Shared Function MettreEnMajuscules (ByVal e As String ) _
As String
Return e. ToUpper
End Function
|
On peut aussi utiliser les expressions lambda multilignes:
Dim nums () As Integer = {1, 2, 3, 4, 5}
nums = Array . FindAll (nums, Function (n)
Console. WriteLine (" testing " & n)
Return n > 2
End Function )
|
ForEach:
Exécute une action spécifiée sur chaque élément du tableau spécifié.
Syntaxe de la forme:
Array.ForEach(MyArray, Action)
Exemple: On a un tableau d'Integer, on veut afficher ces nombres et leurs carrés.
On va créer une sub ShowCarré qui reçoit un Integer et affiche le carré.
Il faut ensuite créer une 'Action', un delegate qui pointe sur la Sub.
Enfin, utiliser Array.ForEach.
Sub Demo
Dim nums () = {2, 3, 5, 4}
Dim action As New Action (Of Integer)(AddressOf ShowCarré)
Array . ForEach (nums, action)
End Sub
Private Shared Sub ShowCarré (ByVal val As Integer)
Console. WriteLine (" {0:d} Carré = {1:d} " , val, val * val)
End Sub
|
On peut utilisez une expression lambda, voir le chapitre plus loin.
Dim nums () = {2, 3, 5, 4}
Array . ForEach (nums, Sub (n)
Console. Write (" Nombre: " )
Console. WriteLine (n)
End Sub )
Array . ForEach (nums, Sub (n) Console. WriteLine (n))
|
V-H-3. Exemple courant d'utilisation des tableaux
Exemple détaillé:
Créer un tableau de 6 éléments, mettre dans chaque élément du tableau le carré de son indice, afficher le contenu du tableau.
Cela montre l'intérêt d'utiliser une boucle pour balayer tous les éléments d'un tableau. Première boucle pour remplir le tableau, seconde boucle pour afficher.(Une boucle For ..Next est ici utilisée, on verra cela plus loin.)
Dim arr (5) As Integer
Dim i As Integer
For i = 0 To arr. GetUpperBound (0)
arr (i) = i * i
Next i
For i = 0 To arr. GetUpperBound (0)
Console. WriteLine (" arr( " & i & " ) = " & arr (i))
Next i
|
Faire une boucle allant de 0 au dernier élément du tableau (For i=0 to ..)
Dans chaque élément du tableau mettre le carré de son indice (arr(i)=i*i )
Nouvelle boucle pour afficher les noms des différents éléments et leur contenu. (Console.WriteLine() affiche sur la console le nom de l'élément et son contenu)
Le programme génère la sortie suivante :
arr(0) = 0
arr(1) = 1
arr(2) = 4
arr(3) = 9
arr(4) = 16
arr(5) = 25
|
Exemple de recherche dans un tableau:
Dans un tableau de String rechercher dans quel élément et à quelle position se trouve la string "MN".
Dim Tableau () As String = {" ABCDEFG " , " HIJKLMNOP " }
Dim AChercher As String = " MN "
Dim i As Integer
Dim position As Integer
For i = 0 To Tableau. Length - 1
position = Tableau (i). IndexOf (AChercher)
If position >= 0 Then Exit For
Next i
|
Exemple de tri de 2 tableaux:
On crée un tableau de clés et un tableau des valeurs, à chaque clé est liée une valeur.
On trie à partir du tableau des clés myKeys , le tableau myValues est modifié pour 'suivre' le tri des clés. La Sub PrintKeysAndValues affiche les résultats.
Public Shared Sub Main ()
Dim myKeys () As String = {" red " , " GREEN " , " YELLOW " , " BLUE " , " purple " , " black " , " orange " }
Dim myValues () As String = {" strawberries " , " PEARS " , " LIMES " , " BERRIES " , " grapes " , " olives " , " cantaloup " }
Console. WriteLine (" Tableau non trié: " )
PrintKeysAndValues (myKeys, myValues)
Array . Sort (myKeys, myValues, 1, 3)
Console. WriteLine (" Après tri d'une partie du tableau: " )
PrintKeysAndValues (myKeys, myValues)
Array . Sort (myKeys, myValues)
Console. WriteLine (" Après tri de la totalité du tableau: " )
PrintKeysAndValues (myKeys, myValues)
End Sub
Public Shared Sub PrintKeysAndValues (ByVal myKeys () As [String ], ByVal myValues () As [String ])
Dim i As Integer
For i = 0 To myKeys. Length - 1
Console. WriteLine (" {0,-10}: {1} " , myKeys (i), myValues (i))
Next i
Console. WriteLine ()
End Sub
|
Création de tableau avec CreatInstance.
Dim myArray As Array = Array . CreateInstance (GetType (Int32), 5)
Dim i As Integer
For i = myArray. GetLowerBound (0) To myArray. GetUpperBound (0)
myArray. SetValue (i + 1, i)
Next i
|
Merci Microsoft pour les exemples.
V-I. Les 'Collections'
Une alternative aux tableaux est l'usage de Collection.
Les Collections permettent de regrouper des données. Les collections sont très utilisées dans la programmation 'Objet'.
Une collection fonctionne plutôt comme un groupe d'éléments dans laquelle il est possible d'ajouter ou d'enlever un élément à n'importe quel endroit sans avoir à se préoccuper de la taille de la collection, ni ou se trouve l'élément.
Le nombre d'élément n'est pas défini au départ comme dans un tableau. Dans une collection, il n'y a aucun élément au départ, puis il n'y a que les éléments que l'on a ajouté.
Les éléments sont repérés grâce à un index ou avec une Clé unique
Les items affichés dans une ListBox donnent une idée concrète de ce qu'est une collection.
V-I-1. Exemple simpliste
Soit la collection Col, au départ elle est vide.
J'ajoute des éléments (ou items) à cette collection.
Col.Add ("Toto")
Voici la collection:
La collection a maintenant 1 élément (On dit un Item).
Je fais maintenant:
Col.Add("Lulu")
Col.Add("Titi")
La collection a 3 éléments maintenant, l'élément (on dit Item) 0, 1, 2.
Je fais :
Col.Remove(1) enlève le deuxième élément. (Attention on compte les éléments à partir de l'élément 0).
La collection n'a plus que 2 éléments maintenant.
On voit que le nombre d'éléments n'est pas connu à l'avance, il varie en fonction des éléments ajoutés (ou retirés)
Un élément est repéré par son indice.
Col.Item(1) contient "Titi" (le second Item de la collection)
Remarque:
J'ai pris une collection de 'Base 0': le premier élément à l'indice 0, c'est habituel dans les classes du Framework; il existe aussi des collections (celles venant de Visual Basic) de Base 1.
V-I-2. Classification des collections
Il est intéressant de classer les collections par fonction:
Il y a les List, comme dans l'exemple simpliste. On a un Index pour repérer les éléments.(Pas de clé).
Il y a les Dictionnaires, chaque élément à une clé, on parle de Collection Clé-Valeur.
On utilise la clé pour retrouvé une valeur.
Certaines collections combinent List et Dictionnaire, d'autres sont triées automatiquement.
Enfin il y a des collections particulières: les Piles, Queue, HashSet, SortedSet....
Certaines collections peuvent contenir des objets, d'autres des Strings ou des Bytes..
Certaines collections utilisent, elles, les génériques: Elles sont faites pour contenir des génériques c'est à dire ce que l'on veut. Quand on utilise la Collection, on indique le type.
Du coup la collection est fortement typée: elle ne peut contenir qu'un type de donnée.
Exemple : List(Of String) est une List ne pouvant contenir que des Strings.
Voici les principales collections:
- Les Listes:ArrayList, List(Of..) VB 2005
- Les Dictionnaires:HashTable, Dictionnary
- Les Listes-Dictionnaires:SortedList,DictionnaryList
- Les Queue et les Queue (Of..)
- Les Piles: Les Stack et les Stack (Of..)
- Les Listes chaînées Les LinkedList(Of....) VB 2005
- Gestion des ensembles: Les HashSet VB 2008
- Collections travaillant sur les Bits:BitArray, BitVector32
- Collections triée: SortedList, SortedDictionnary SortedSet du framework 4
- Autres: ObservableCollection
V-I-3. ArrayList
Fait partie de System.Collections. c'est une Classe .Net. Il faut donc ajouter en haut du module:
Imports System. Collections
|
C'est une 'Liste' d'objets, d'Item:
La ArrayList est une collection particulière: On peut y mettre des objets : chaînes, nombres... rien n'empêche que le premier élément soit un entier, le second une chaîne… . Il n'y a pas de clé.
 |
Attention le premier élément, le premier Item, est ici l'élément 0 (l'index va de 0 à count-1) ; c'est du .NET!!
|
Exemple:
Dim L As New ArrayList ()
Dim L As ArrayList = ArrayList. Repeat (" A " , 5)
L. Add (" Bonjour " )
MsgBox (L (0))
|
L.Add() permet d'ajouter un élément; on affiche le premier élément L(0)
On pourra aussi écrire L.Item(0) pour pointer le premier élément, en effet les éléments sont L.Item(0), L.Item(1), L.Item(2)...
 |
Attention c'est le nombre d'éléments. S'il y a 3 éléments dans la ArrayList ce sont les éléments d'index 0,1,2.
|
L. Remove (" Bonjour " )
L. RemoveAt (0)
L. Sort ()
L. Clear ()
L. Contains (élément)
|
Insert permet d'insérer à un index spécifié:
L. Insert ( position, Ainserrer)
|
InsertRange insère une ArrayList dans une autre ArrayList.
Recherche d'un élément dans une collection NON TRIEE avec IndexOf:
Dim l As New ArrayList
Dim i As Integer
l. Add (" toto " )
l. Add (" lulu " )
i = l. IndexOf (" lulu " )
MsgBox (i. ToString )
|
On rappelle qu'il existe aussi LastIndexOf qui démarre par la fin et une surcharge permettant de débuter la recherche à partir d'un indice donné. Comment rechercher "lulu" à partir du 3ème élément).
Recherche d'un élément dans une collection TRIEE avec BinarySearch:
Dim l As New ArrayList
Dim i As Integer
l. Add (" toto " )
l. Add (" lulu " )
l. Sort ()
i = l. BinarySearch (" lulu " )
MsgBox (i. ToString )
|
Pour parcourir une collection, 3 méthodes :
-Avec l'index de l'item
For i= 0 to L. Count - 1
A= L. Item (i)
Next i
|
NB: Comme vu plus haut, on utilise Count pour trouver le nombre d'élément, aussi la boucle doit balayer de 0 à count-1. Enfin bien se souvenir que A est un Objet, il faudra le convertir pour l'utiliser:
Dim s As String = CType (A,String )
|
-Avec For Each
Dim o As Objet
For Each o in L
A= o
Next
|
Attention, A est un objet. De plus on verra que dans une boucle For Each, on ne peut pas modifier la collection.
-Avec l'objet IEnumerator (débutant passe ton chemin)
On crée un objet C de type IEnumerator pour parcourir la collection, cet objet a 3 propriétés:
MoveNext qui avance d'un élément dans la collection. S'il ne peut plus avancer (s'il est déjà après le dernier) il retourne False
Reset qui place l'élément courant au début, avant le premier élément (Comme au départ)
Current désigne l'élément courant.
Exemple montrant la seule manière de faire pour parcourir la collection:
Dim L As New ListArray
Dim C As IEnumerator= L. GetEnumerator ()
While C. MoveNext ())
A= C. Current
End While
|
 |
Attention, si Option Explicit=On
|
Les éléments de la ListArray étant des objets, on ne peut pas les affecter à une variable String par exemple, il faut écrire:
Str = CType (L (0), String )
|
Remarque:
V-I-4. List (Of)
A partir de 2005 on a des collections que l'on peut typer, c'est à dire qu'elles ne pourront contenir qu'un type de donnée, que des String, des entiers, des instances de telle classe... On parle de collections génériques. Le terme Of permet de définir le type de la collection.
Nécessite:
Imports System. Collections . Generic
|
Créons une liste ne contenant que des 'Decimal'.
Dim lst As New List (Of Decimal)
|
Exemple: créons une collection de String List(Of String): Elle est typée car elle ne peut contenir que des 'String'.
Dim lst As New List (Of String )
|
Il s'agit d'une List avec Index.
lst(0) est le premier élément.
ou lst.item(0)
On ajoute une String:
Elle devient le dernier élément de la liste.
Comment affecter cet élément à une String?
Dim S As String = lst. Item (0)
|
L'item est bien typé : même avec 'Option Strict=on' pas besoin de CType.
Nombre d'éléments de la list:
On peut à partir de vb 2010 'remplir' simplement une collection grâce à 'From':
Dim names As New List (Of String ) From {" Christa " , " Brian " , " Tim " }
|
Noter bien le New.
On peut aussi remplir avec un tableau ou ajouter une List par un AddRange:
Dim input () As String = { " Brachiosaurus " , _
" Amargasaurus " , _
" Mamenchisaurus " }
Dim Animals As New List (Of String )(input)
Animals. AddRange (2, Animals)
|
La liste contient t-elle "toto"?
Dim present As Boolean = lst. Contains (" toto " )
|
Present = True si la liste contient "toto".
Insérer un élément à une position donnée:
Supprimer un élément à une position donnée:
lst. Remove (" lulu " )
lst. RemoveAt (3)
lst. RemoveRange (3,2)
|
Parcourir tous les éléments et les afficher:
For Each element As String In lst
Console. WriteLine (element)
Next
|
Rechercher un élément dans la liste:
lst. IndexOf (" lulu " )
lst. IndexOf (" lulu " , 2,7) recherche à partir de l
|
Il existe aussi LastIndexOf.
Sur une list triée on utilise BinaryScearch, voir ArrayList, c'est parreil.
On peut copier une List ou partie de List dans un tableau:
Dim array (14) As String
lst. CopyTo (array )
lst. CopyTo (array , 6)
lst. CopyTo (2, array , 12, 3)
Dim output () As String = lst. GetRange (2, 3). ToArray ()
|
On voit que List (Of) possède toutes les méthodes des ArrayList, mais en plus il existe des méthodes propres aux collections génériques (à partir du Framework 2):
- Exists
- List contient-il des éléments qui correspondent aux conditions définies par un prédicat?
- TrueForAll
- Chaque élément dans List correspond-il aux conditions définies par un prédicat?
- Find
- Recherche un élément qui correspond aux conditions définies par le prédicat et retourne la première occurrence.
- FindLast
- Idem pour la dernière occurrence.
- FindAll
- Récupère tous les éléments qui correspondent aux conditions définies par le prédicat.
- ConvertAll
- Chaque élément est passé individuellement à un Converter, et les éléments convertis sont enregistrés dans la nouvelle collection.
- RemoveAll
- Efface les éléments qui correspondent au Predicat
La syntaxe est dela forme ListeResultat= List.Find(Liste, AdresseOf Predicat)
Un Predicat est une Fonction qui retourne True si une condition est remplie.
Exemple:
Exemple 1:
Avec FindAll:
J'ai une list 'Animals', je veux mettre dans 'listResult' tous les éléments de Animals qui se terminent par 'us'.
On crée une liste (listResult) qui grâce à FindAll se chargera des éléments de Animals qui répondent à une condition:
Dim Animals As New List (Of String ) From {" Compsognathus " , _
" Amargasaurus " , " Oviraptor " , " Velociraptor " , _
" Deinonychus " , " Dilophosaurus " , " Gallimimus " , _
" Triceratops " }
Dim listResult As List (Of String ) = Animals. FindAll (AddressOf SeTermineParUS)
|
En argument de FindAll on a l'adresse d'une fonction: ici la fonction 'SeTermineParUS'. Pour chaque élément de Animals si SeTermineParUS retourne True, l'élément correspondant est passé dans listResult.
Voici la fonction de test, le Predicat.
Private Shared Function SeTermineParUS (ByVal s As String ) As Boolean
If (s. Length > 2) AndAlso (s. Substring (s. Length - 2). ToLower () = " lu " ) Then
Return True
Else
Return False
End If
End Function
|
Exemple 2:
Avec ConvertAll on obtient à partir d'une première liste, une seconde liste ou chaque élément à été convertit par une fonction.
Ici on a une liste d'animaux , on va obtenir une seconde liste avec des noms court (4 caractères).
Dim Animals As New List (Of String ) From {" Compsognathus " , _
" Amargasaurus " , " Oviraptor " , " Velociraptor " , _
" Deinonychus " , " Dilophosaurus " , " Gallimimus " , _
" Triceratops " }
Dim Animals2 As New List (Of String )
Animals2 = Animals. ConvertAll (New Converter (Of String , String )(AddressOf RaccourcirNom))
For Each dinosaur As String In Animals2
Console. WriteLine (dinosaur)
Next
Private Shared Function RaccourcirNom (ByVal x As String ) As String
Return x. Substring (0, 4)
End Function
|
Trier une List:
Soit une liste (Of String) de noms d'animaux, on veut trier par ordre alphabétique:
On utilise Sort.
Dim Animals As New List (Of String ) From {" Compsognathus " , _
" Amargasaurus " , " Oviraptor " , " Velociraptor " , _
" Deinonychus " , " Dilophosaurus " , " Gallimimus " , _
" Triceratops " }
Animals. Sort ()
|
Mais on peut indiquer une Fonction qui va definir la manière de trier: Ici je veux trier en fonction de la longueur des String:
Je vais indiquer l'adresse de ma fonction de comparaison comme argument de Sort:
Dim Animals As New List (Of String ) From {" Compsognathus " , _
" Amargasaurus " , " Oviraptor " , " Velociraptor " , _
" Deinonychus " , " Dilophosaurus " , " Gallimimus " , _
" Triceratops " }
Animals. Sort (AddressOf CompareByLength)
Private Shared Function CompareByLength ( _
ByVal x As String , ByVal y As String ) As Integer
Return x. Length . CompareTo (y. Length )
End Function
|
V-I-5. HashTable
C'est un 'Dictionnaire' qui comporte des couples clé-élément, des paires clé-valeur.
Ces couples sont de type Objet-Objet.
La clé toujours unique permet de retrouver la valeur, La clé ne doit pas être vide non plus.
Créons une Hashtable:
H.Add(Clé,Valeur) Ajoute un élément
H.Item(Clé) Retourne l'élément correspondant à une clé.
H.ContainsKey(Clé) Retourne True si la Clé est dans la table.
H.ContainsValues(Valeur) Retourne True si la valeur est dans la table.
H.Clear Efface tous les éléments
H.Remove(Clé) Supprime l'élément ayant une clé spécifiée.
Les collections H.Values et H.Keys contiennent les valeurs et les clés.
Exemple:
Dim myHT As New Hashtable ()
myHT. Add (" un " , " premier " )
myHT. Add (" deux " , " second " )
myHT. Add (" trois " , " troisième " )
myHT. Add (" quatre " , " quatrième " )
myReponse= myHT. Item (" trois " )
Dim myEnumerator As IDictionaryEnumerator = myHT. GetEnumerator ()
While myEnumerator. MoveNext ()
MsgBox ( myEnumerator. Key + myEnumerator. Value )
End While
|
Attention on n'utilise pas de numéro d'index mais uniquement la clé.
En interne, pour chaque élément, la clé est 'hachée' pour créer un code de hashage qui sert à pointer l'élément et sa valeur (voir le chapitre sur l'algorithme), ce procédé accélère la recherche de la valeur à partir de la clé.
V-I-6. Dictionnary (Of)
A partir de VB 2005, il y a cette collection de type Dictionnaire (Clé-Valeur) mais elle utilise les génériques.
La clé doit être unique (pas de doublon de clé).
La récupération d'une valeur à partir de sa clé est très rapide.(Utilisation d'un hachage)
Of permet de choisir le type de la clé et celui des valeurs.
Créons un Dictionnary avec des clés de type String et des valeurs de type String.
Dim Dic As New Dictionary (Of String , String )
|
' Ajout d'élément
Dic. Add (" txt " , " notepad.exe " )
Dic. Add (" bmp " , " paint.exe " )
|
Depuis vb 2010 on peut ajouter rapidement des éléments:
Dim days = New Dictionary (Of Integer, String ) From
{{0, " Sunday " }, {1, " Monday " }}
|
' Ajout d'élément en vérifiant avant si la clé n'existe pas
If Not Dic. ContainsKey (" ht " ) Then
Dic. Add (" ht " , " hypertrm.exe " )
End If
|
' Modifier la valeur correspondant à la clé 'doc'
Dic (" doc " ) = " winword.exe "
|
'Parcours du Dictionary (le type de clé/Value est KeyValuePair).
For Each kvp As KeyValuePair (Of String , String ) In Dic
Console. WriteLine (" Key = {0}, Value = {1} " , kvp. Key , kvp. Value )
Next kvp
|
' Récupérer une valeur correspondant à une clé
Dim tt As String = Dic (" rtf " )
|
'TryGetValue permet de rechercher une valeur correspondant à une clé, retourne False si la clé n'existe pas (sans déclencher d'erreur).
Dim value As String = " "
If Dic. TryGetValue (" tif " , value) Then
Console. WriteLine (" For key = " " tif " " , value = {0}. " , value)
Else
Console. WriteLine (" Key = " " tif " " non trouvée. " )
End If
Dic. . ContainsKey (" ht " ) permet aussi de tester si une clé existe.
|
'Enlever un élément
V-I-7. SortedList SortedList (Of)et SortedSet
SortedList:
Combine List et Dictionnaire avec un tri automatique.
Il permet l'accès aux valeurs par l'intermédiaire des clés associées ou des index.
C'est un hybride de HashTable et de Array.
On ajoute un élément par mySL.Add(Clé,Valeur)
La séquence d'index est basée sur la séquence de tri. Quand un élément est ajouté, il est inséré dans l'ordre de tri adéquat, et l'indexation s'ajuste en conséquence. Le tri est donc automatique.
On peut donc lire une valeur par sa Clé ou son Index:
- Quand la clé d'un élément permet d'accéder à celui-ci à l'aide de la propriété d'indexeur Item, l'élément se comporte comme Hashtable.
- Quand l'index d'un élément permet d'accéder à celui-ci à l'aide de GetByIndex ou de SetByIndex, l'élément se comporte comme Array (tableau avec un Index).
mySL. GetKey (3)
mySL. GetByIndex (3)
|
SortedList maintient en interne deux tableaux , un tableau pour les clés et un autre pour les valeurs associées.
Index de base 0: Le premier élément est 0.
Exemple:
Dim mySL As New SortedList ()
mySL. Add (" 1 " , " Hello " )
mySL. Add (" 2 " , " World " )
mySL. Add (" 3 " , " ! " )
Console. WriteLine (" Count: {0} " , mySL. Count )
Console. WriteLine (" Capacity: {0} " , mySL. Capacity )
Dim i As Integer
For i = 0 To mySl. Count - 1
Console. WriteLine ( myList. GetKey (i)& myList. GetByIndex (i))
Next i
|
Les SortedList(Of..) sont des SortedList génériques avec Clé et valeur ,triées sur la clé. Ressemble à SortedDictionary, mais occupe moins de mémoire et est moins rapide pour les insertions/suppressions.
Les SortedDictionnary(Of..) sont des collections génériques avec Clé et valeur ,trié sur la clé.
Les SortedSet: (Framework 4)
Collections générique.
Un SortedSet maintient un ordre trié à mesure que les éléments sont insérés et supprimés sans que les performances en soient affectées.Les éléments dupliqués ne sont pas autorisés.
Il est possible de créer un comparer qui sera utilisé par le tri.
Dim mediaFiles1 As SortedSet (Of String ) = New SortedSet (Of String )(New ByFileExtension)
Public Class ByFileExtension
Implements IComparer (Of String )
. . . .
End Class
|
V-I-8. Queue
Collection d'objets de type FIFO (First In, First Out)
Premier arrivé premier servi.
C'est la queue devant un cinéma, le premier arrivé, prend son billet le premier.
Les objets (String, Integer....) stockés dans Queue sont insérés à une extrémité et supprimés à l'autre.
Le nombre d'élément de la queue est géré automatiquement.
DeQueue supprime et retourne l'objet de début de liste.
EnQueue ajoute un objet en fin de liste.
Peek retourne l'objet de début sans le supprimer.
Dim myQ As New Queue ()
myQ. Enqueue (" One " )
myQ. Enqueue (" Two " )
myQ. Enqueue (" Tree " )
Console. WriteLine ( myQ. Count )
Console. WriteLine (myQ. Dequeue ())
|
Affiche le premier sorti en le sortant. "one" dans notre exemple.
S'il n'y a plus d'élément cela lève une exception (une erreur)
il faut donc gérer l'exception ou contrôler le nombre d'élément avec la propriété Count.
If MyQ. Count > 0 then
myQ. Dequeue . .
End If
|
Console. WriteLine (myQ. Peek ())
|
Affiche le premier élément sans l'enlever de la Queue
Efface tous les éléments de la queue
Les Queue(Of..) sont des Queue mais avec un généric.
V-I-9. Stack
Collection d'objets de type pile ( ou stack) LIFO (Last In, First Out)
Dernier entré, premier sortie.
Ce type de stack (pile) est très utilisé en interne par les programmes informatiques: on stocke dans une stack les adresses de retour des procédures appelées, au retour on récupère l'adresse du dessus.
Push insère un objet en haut de la pile
Pop enlève et retourne un objet en haut de la pile
On peut utiliser une pile dans un programme pour gérer le déplacement de l'utilisateur dans un arbre, les éléments en cours sont stockés par Push, pour remonter en chemin inverse, on Pop.
 |
Attention le premier élément est ici l'élément 1 (élément d'index 1 à count)
|
Exemple:
Dim MaPile As New Stack ()
Dim Str As String
MaPile. Push (" A " )
MaPile. Push (" B " )
MaPile. Push (" C " )
Srt = MaPile. Pop ()
|
Str est maintenant égal à "C"
 |
Attention, si Option Explicit=On, les éléments de la pile étant des objets, on ne peut pas les affecter à une variable String, il faut écrire:
|
Str = CType (MaPile. Pop (), String )
|
Si la pile est vide et que l'on 'Pop', une exception non gérée du type 'System.InvalidOperationException' se produit.(une erreur se produit et cela plante!!), là aussi vérifier que MaPile.Count (qui indique le nombre d'éléments dans la pile) n'est pas égale à 0 avant de 'Poper'.
Les Stack(Of..) sont des track mais avec un généric.
V-I-10. Les LinkedList (Of)
Ce sont des Listes Chaînées de générique, chaque élément comportant une propriété Value(qui contient la valeur de l'élément), Next et Previous. A partir d'un élément, on peut connaître le suivant ou le précédent.
Voir le chapitre sur les algorithmes qui explique la notion de liste chaînée.
Schémas d'une liste chainée:
Imports System. Collections . Generic
Dim words () As String = {" the " , " fox " , " jumped " , " over " , " the " , " dog " }
Dim lk As New LinkedList (Of String )(words)
Ajouter le mot
lk. AddFirst (" today " )
lk. RemoveLast ()
Dim current As LinkedListNode (Of String ) = lk. FindLast (" the " )
lk. AddAfter (current, " old " )
Dim element As LinkedListNode (Of String ) = current. Previous
lk. AddBefore (current, element)
current. Value
current. Previous . Value
lk. First . Value
lk. Last . Value
Containst, Count
|
V-I-11. HashSet (Of)
Travailler sur les ensembles.
Il s'agit d'une collection de génériques sans ordre qui contient des éléments uniques. HashSet possède comme toutes les collections Add, Remove et Contains.. et fournit plusieurs opérations d'ensembles (notamment l'union, l'intersection et la différence symétrique) ce qui permet de prendre en charge la plupart des opérations mathématiques qui sont généralement réalisées sur des ensembles (sens mathématique du terme).
Dim hs As New HashSet (Of String )
hs. Add (" toto " )
hs. Add (" lulu " )
hs. Add (" titi "
|
La méthode Add renvoie True ou False pour indiquer si elle a fonctionné (s'il n'y avait pas déjà dans la HashSet l'élément que l'on veut ajouter).
Dim caMarche As Boolean = hs. Add (" toto " )
|
On peut effacer un élément:
On peut effacer sous condition:
Exemple: effacer tous les éléments contenant un "t":
hs. RemoveWhere ( Adress Of Test)
|
'La fonction Test reçoit chaque string de la table et retourne un booléen qui indique si la condition est remplie ce qui déclenche le Remove.
Private Shared Function Test (ByVal s As String ) As Boolean
Return (Instr (s," t " )< > 0)
End Function
|
On peut ajouter la collection hs2 à hs grâce à UnionWith:
Les éléments doublons (qui existent déjà dans hs) ne sont pas ajoutés.
Cela correspond à un And.
On peut rechercher les éléments communs à hs2 et à hs grâce à IntersectWith:
hs contient maintenant les éléments qui étaient présents dans hs et hs2
Cela correspond à un Or.
On supprime tous les éléments de hs qui sont aussi contenus dans la collection passée en paramètre (hs2) avec ExceptWith.
hs contient maintenant les éléments qui n'étaient pas présents dans hs et hs2.
On peut rechercher les éléments contenus dans hs2 et dans hs mais pas dans les 2 grâce à SymmetricExceptWith:
hs. SymmetricExceptWith (hs2)
|
hs contient maintenant les éléments qui étaient présents dans hs ou hs2 mais pas les deux.
On peut rechercher si hs2 est un sous-ensemble de hs grâce à IsSubsetOf:
Dim b As Boolean= hs. IsSubsetOf (hs2)
|
b est égal à True si hs est un sous ensemble de hs2 (tous les éléments de hs sont dans hs2).
Il existe aussi:
IsProperSubstOf qui retourne True si hs est un sous-ensemble de hs2 et si hs différent de hs2 (sous ensemble strict).
On peut rechercher si hs2 est un sur-ensemble de hs grâce à IsSupersetOf:
Dim b As Boolean= hs. IsSupersetOf (hs2)
|
b est égal à True si hs est un sur ensemble de hs2 (tous les éléments de hs2 sont dans hs).
Il existe aussi:
IsProperSupersetOf qui retourne True si hs est un sur ensemble de hs2 et si hs est différent de hs2 (sur ensemble strict).
V-I-12. BitArray
Crée une collection de booléens (codés sur un bit). La valeur de chaque élément est True ou False.
Dim myBA As New BitArray (5)
Dim myBA As New BitArray (5, False )
Dim myBA () As Boolean = {True , True , False , False , False }
Dim myBA As New BitArray (myBytes)
|
Le premier élément est l'élément 0.
On peut mettre tous les bits à True avec SetAll:
' Mettre le dernier Bit à False avec Set.
myBA. Set (myBA. Count - 1, False )
|
'Obtenir la valeur du second Bit.
myBA(1) ou myBA.Item(1) donnent aussi la valeur du second Bit.
On peut effectuer des opérations logiques entre 2 BitArray (Or, Xor, And Not):
Exemple pour Or:
Count et Length donnent le nombre d'éléments, mais Count est en lecture seule, Length permet, lui, de modifier le nombre d'éléments.
La Collection BitVector32:
Ne permet de travailler que sur 32 bits mais est plus rapide.
Il faut avoir ajouté: Imports System.Collection.Specialized.
V-I-13. StringCollection
L'espace System.Collections.Specialized fournit ces nouveaux types de collection très spécifiques, elles ne sont faites que pour un seul type:
StringCollection ne peut contenir que des chaînes (cela devrait aller plus vite)
Dim myCol As New StringCollection ()
Dim myArr () As [String ] = {" rouge " , " vert " , " orange " , " vert " ,)
myCol. AddRange (myArr)
myCol. Add (" marron " )
myCol. Insert (3, " bleue " )
myCol. Remove (" orange " )
Dim i As Integer = myCol. IndexOf (" vert " )
While i > - 1
myCol. RemoveAt (i)
i = myCol. IndexOf (" vert " )
End While
If myCol. Contains (" jaune " ) Then . .
Dim myArr2 (myCol. Count ) As [String ]
myCol. CopyTo (myArr2, 0)
myCol. Clear ()
Dim myEnumerator As System. Collections . IEnumerator = myCol. GetEnumerator ()
While myEnumerator. MoveNext ()
Console. WriteLine (" {0} " , myEnumerator. Current )
End While
|
 |
Attention le premier élément est ici l'élément 0 (l'index va de 0 à count-1); c'est du .NET!!
|
V-I-14. ObservableCollections, SortedSet(Of T)
Pour mémoire on se souvient qu'il existait un Type Collection en VB6, de Base 1, à oublier.
Par contre, à partir de VB 2008 existent les collections ObservableCollections qui peuvent être 'Bindées' (attachées) à des Objets visuels (comme une List ou une Grid WPF) et qui permettent la mise à jour automatique du contrôle quand on modifie la collection.
Enfin, à partir de VB 2010 existent SortedSet(Of T) . Un SortedSet(Of T) maintient un ordre trié à mesure que les éléments sont insérés et supprimés sans que les performances en soient affectées.Les éléments dupliqués ne sont pas autorisés.
V-I-15. Généralisation de la notion de collection
Certains objets ont une liste de données, d'items, Vb les organise en Collections.
Une collection peut donc faire partie des propriétés d'un objet.
Exemple:
On verra plus loin qu'un contrôle nommé TextBox peut contenir du texte, ce contrôle à une collection nommée .lines qui contient les lignes de texte (s'il y en a plusieurs)
Si le texte contient 3 lignes, elles seront dans la collection 'lines'.
Texbox1. lines (0)
Textbox1. lines (1)
Textbox1. lines (2)
|
L'indice des éléments va de 0 à count-1
Autres exemples:
Les contrôles ListBox possèdent une collection 'Items' dans laquelle sont placés tous les éléments contenus dans la liste. Pour ajouter un élément on utilise la méthode Add de la collection Items:
Un tas d'objets possèdent des collections.
Encore plus: chaque formulaire possède une Collection 'Controls'. Il s'agit d'une collection qui contient tous les contrôles de ce formulaire.
V-I-16. Pourquoi le premier élément est-il 0 ou 1 ?
 |
Le .NET Framework normalise les collections comme étant des collections de base zéro (ArrayList par exemple). Visual Basic fournit des collections de base 1 (Comme Collection qu'il ne faut plus utiliser).
|
V-I-17. Exemples sur les collections
Créer une ArrayList, une queue, ajouter la queue à la ArrayList, chercher un élément, insérer un élément.
Les collections font partie de l'espace de nom Systeme.Collections
Imports System. Collections
Dim myAL As New ArrayList ()
myAL. Insert (0, " un " )
myAL. Insert (1, " deux " )
Dim myQueue As New Queue ()
myQueue. Enqueue (" trois " )
myQueue. Enqueue (" quatre " )
myAL. InsertRange (1, myQueue)
myAL. Insert (myAL. IndexOf (" deux " ), " moins de deux " )
myAL. Insert (myAL. Count , " !!! " )
|
V-I-18. Lexique anglais=>Français
Array = tableau, table.
length= longueur
Key= clé
Remove (to)= enlever
Stack= tas
V-J. Les 'Structures'
En règle générale, une structure est utilisée comme conteneur pour un petit jeu de variables.
Permet de regrouper des données de type différent:
(En Vb6 il y avait les types définis par l'utilisateur, ils sont remplacés par les structures.)
 |
Les structures sont intéressantes quand vous voulez utiliser des variables contenant plusieurs informations de différent type. Les structures sont surtout utilisées dans la programmation non 'objet'(En programmation Objet, on utilisera plutôt les Collections).
|
Exemple :
Vous voulez définir une variable contenant une adresse composée d'un numéro, de la rue, de la ville.
Il faut d'abord définir la structure (au niveau Module ou Class, pas dans une procédure).
Public Structure Adresse
Dim Numero As Integer
Dim Rue As String
Dim Ville As String
End Structure
|
Puis dans une procédure il faut déclarer la variable :
Dim MonAdresse As Adresse
|
La variable MonAdresse est déclarée comme une adresse, elle contient donc:
un numéro qui est dans 'MonAdresse.Numero'
un nom de rue qui est dans 'MonAdresse.Rue'
un nom de ville qui est dans 'MonAdresse.Ville'
On pourra enfin l'utiliser :
MonAdresse. Numero = 2
MonAdresse. Rue = " Grande rue "
MonAdresse. Ville = " Lyon "
|
On peut aussi utiliser le mot clé With pour ne pas avoir à répéter le nom de la variable (et cela va plus vite).
With MonAdresse
. Rue = " Grande rue "
. Ville = " Lyon "
End With
|
With est utilisable sur tous les objets.
Il est possible de travailler sur un tableau de structures:
Dim Adresses (99) as Adresse
Adresses (33). Rue = " Place de la mairie "
|
On peut utiliser une variable de type structure comme paramètre d'une fonction:
Sub AfficheAdresse ( ByVal Une Adresse As Adresse)
. . . Imprimer l
End sub
|
Pour imprimer l'adresse 33 on écrira AfficheAdresse ( Adresse(33))
V-J-1. Tableau dans une structure
Attention quand dans une structure il y a un tableau, il faut l'initialiser:
on veut définir une structure dans laquelle il y a 25 données DriveNumber.
On aurait tendance à écrire:
Public Type DriveInfo
DriveNumber (25) As Integer
DriveType As String
End Type
|
Mais cela ne fonctionne pas!!
En Visual Basic .NET il y a 2 méthodes pour utiliser un tableau dans une structure:
1-Méthode par initialize
Une structure peut comporter une méthode 'Initialize' qui sera exécutée quand on déclare une variable de type structure.
Ici, on a crée une méthode Initialize qui redimensionne le tableau interne à la structure.
Public Structure DriveInfo
Dim DriveNumber () As Short
Dim DriveType As String
Public Sub Initialize ()
ReDim DriveNumber (25)
End Sub
End Structure
|
Exemple de routine utilisant la structure.
Function AddDrive (ByRef Number As Short, ByRef DriveLabel As String ) As Object
Dim Drives As DriveInfo
Drives. Initialize ()
Drives. DriveNumber (0) = 123
Drives. DriveType = " Fixed "
End Function
|
2-Autre manière de faire:
Après la déclaration de la variable, on 'Redimensionne' le tableau.
Public Structure DriveInfo
Dim DriveNumber () As Short
Dim DriveType As String
End Structure
Function AddDrive (ByRef Number As Short, ByRef DriveLabel As String ) As Object
Dim Drives As DriveInfo
Redim Drives. DriveNumber (25)
Drives. DriveNumber (3)= 12
Drives. DriveType = " Fixed "
End Function
|
Si on utilise 100 variables Drives, il faut 'Redim' ou 'Initialize' le tableau pour chaque variable!!
Dim Drives (100) As DriveInfo
For i as Integer = 0 to 100
Drives (i). Initialize
Next i
|
En plus si Dim Drives (100) est en tête d'un module, il faut mettre la boucle dans une procédure.
V-J-2. Allons plus loin
Une structure hérite de System.ValueType
V-J-2-a. Les structures sont des types 'valeur'
Une variable d'un type structure contient directement les données de la structure, alors qu'une variable d'un type classe contient une référence aux données, ces dernières étant connues sous le nom d'objet.
Cela a de l'importance: si je crée une variable avec une structure, que je copie cette variable dans une seconde, le fait de modifier la première variable ne modifie pas la seconde.
Prenons l'exemple donné par Microsoft:
Structure Point
Public x, y As Integer
Public Sub New (x As Integer, y As Integer)
Me. x = x
Me. y = y
End Sub
End Structure
|
On définit une structure Point et on définit une méthode 'New' permettant de saisir les valeurs:
'Public Sub New' est un constructeur.
Pour saisir les valeurs de x et y ont peut utiliser:
Dim a As Point
a. x = 10
a. y = 10
|
ou utiliser le constructeur:
Dim a As New Point (10,10)
|
En partant de la déclaration ci-dessus, le fragment de code suivant affiche la valeur 10 :
Dim a = new Point (10, 10)
Dim b = a
a. x = 100
Console. WriteLine (b. x )
|
L'assignation de a à b crée une copie de la valeur, et b n'est donc pas affecté par l'assignation à a.x. Si, en revanche, Point avait été déclaré comme une classe, la sortie aurait été 100 puisque a et b auraient référencé le même objet.
Enfin, les structures n'étant pas des types 'référence', il est impossible que les valeurs d'un type structure soient nulles ( elles sont égales à 0 après la création).
V-J-2-b. Les structures peuvent contenir plein de choses
On a vu qu'elles peuvent contenir:
- Des variables de différent type.
- Des tableaux.
- Des méthodes : on a vu l'exemple de Initialize et de New.
Mais aussi
- Des objets.
- D'autres Structures.
- Des procédures.
- Des propriétés.
Exemple donné dans l'aide (et modifié par moi) :
Débutant: A relire peut-être ultérieurement quand vous saurez utiliser les Classes.
Cet exemple définit une structure Employee contenant une procédure CalculBonus et une propriété Eligible.
Public Structure Employee
Public FirstName As String
Public LastName As String
Friend EmployeeNumber As Integer
Friend WorkPhone As Long
Private HomePhone As Long
Private Level As Integer
Public Salary As Double
Public Bonus As Double
Friend Sub CalculateBonus (ByVal Rate As Single)
Bonus = Salary * CDbl (Rate)
End Sub
Friend ReadOnly Property Eligible () As Boolean
Get
Return Level >= 25
End Get
End Property
End Structure
|
Utilisons cette structure:
Dim ep As Employee
ep. Salary = 100
ep. CalculateBonus (20)
TextBox1. Text = ep. Bonus . ToString
|
Cela ressemble aux Classes !! Non?
V-J-2-c. Portée
Vous pouvez spécifier l'accessibilité de la structure à l'aide des mots clé: Public, Protected, Friend ou Private ou garder la valeur par défaut, Public. Vous pouvez déclarer chaque membre en spécifiant une accessibilité. Si vous utilisez l'instruction Dim sans mot clé, l'accessibilité prend la valeur par défaut, Public.
Private Mastructure
Public i As Integer
. . .
End Structute
|
En conclusion les structures sont maintenant très puissantes et peuvent contenir autant de choses que les Classes , on verra cela plus loin. Mais les structures sont référencées 'par valeur' alors que les Classes le sont 'par référence'.
Les sources présentés sur cette page sont libres de droits,
et vous pouvez les utiliser à votre convenance. Par contre cette page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © .
Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu :
textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
Cette page est déposée à la SACD.
|