Une collection est une structure de données qui permet à tout développeur java de stocker des données en mémoire et facilement accessible. Les collections peuvent dans certains cas être vues comme des tableaux de données évolués car ces dernières proposent d'innombrables méthodes d'accès afin de faciliter l'accès et la manipulation des données.
1. Qu'est qu'une collection
Dans le langage Java, une collection est un objet qui implémente l'interface de base java.util.Collection. Une collection n'est pas une Map. Une collection est un objet dont la structure sou-jacente est un tableau à accès indexé. Il existe plusieurs catégories de collection.
2. Les List
Il s'agit du type de collection le plus utilisé. Aucune contrainte sur les objets, aucune contrainte sur la taille de la liste. De plus les objets contenues dans une telle collection sont accessibles directement par un index. L'interface java.util.List est implémentée par plusieurs classes telles que: ArrayList, LinkedList, Vector et bien d'autres.
- Toujours utiliser un ArrayList si vous avez juste besoin de stocker dans une collection un ensemble d'objets sans contrainte spécifique. C'est la collection la plus simple
- Dans un contexte multithreadé (c'est à dire si votre collection est potentiellement accessible par plusieurs thread de manière concurrente), il est préférable d'utiliser un Vector
- Si vous avez besoin de conserver un lien de precedence ou de succession entre vos objets dans la collection, il faudra alors utiliser une LinkedList. Mais attention, cette structure de données est très consommatrice de mémoire
Il est très important en matière de gestion de la mémoire de votre programme, d'indiquer la taille de votre liste, lors de sa création.
Pour créer une List
List<User> users = new ArrayList<>();
List<Value> values = new Vector<>();
List<Role> roles = new LinkedList<>();
Pour ajouter un élément
Il faut utiliser la méthode add(...)
users.add(new User("Java", "TutorialsHub"));
values.add(new Value(100_000_000d, 200_000d));
roles.add(new Role(1L, "admin", "Administrator"));
L'élément qui vient d'être ajouter occupe aussitôt la dernière position dans la liste. Et cette position est: list.size() - 1
Pour récupérer un élément
Il faut utiliser la méthode get(...)
User user = users.get(0);
Value value = values.get(0);
Role role = roles.get(0);
Pour supprimer un élément
Il faut utiliser la méthode remove(...)
users.remove(0);
values.remove(0);
roles.remove(0);
Récupérer la taille
La méthode size() est utilisée pour récupérer la taille d'une liste
int size = users.size();
Tester si la collection est vide
La méthode isEmpty() permet de savoir si une collection est vide ou pas en retournant un booléen à cet effet. si la valeur retournée est: true, alors la liste est vide dans le cas contraire, elle contient au moins un élément.
if(values.isEmpty()) {
}
3. Les Set
Les Set ont pour particularité de ne pas accepter de doublons. En effet, cette collection n'ajoutera un élément supplémentaire que si ce objet n'existe pas dans cette collection. La collection testera l'existence d'un objet avec les autres objets présents dans la collection en appelant la méthode equals sur chaque objet: e1.equals(e2). L'interface java.util.Set est implémentée par plusieurs classes telles que: HashSet, LinkedHashSet, TreeSet et bien d'autres.
- Toujours utiliser un HashSet si vous souhaitez disposer d'une collection dont les objets contenus sont uniques, sans doublons. En matière de Set, les HashSet constitue l'implémentation la plus simple.
- A l'instar, des LinkedList, les LinkedHashSet, permettent aux éléments contenus dans la collection de tenir une référence vers l'objet qui précède et une référence vers l'objet qui succède dans la collection. De par cette particularité, la consommation mémoire des LinkedHashSet est plus importante que celle des autres Set.
- Si vous souhaitez disposer d'un Set dont les valeurs sont automatiquement triés et donc ne nécessitant pas de les trier après coup, vous devez alors utiliser une TreeSet. La contrainte ici est que tous les éléments doivent implémenter l'interface java.lang.Comparable. Par contre vu que tout ajout dans cette collection impose qu'elle soit automatiquement triée, alors l'ajout est une opération relativement couteuse dans un TreeSet comparée aux autres collections.
Il est très fortement conseillé d'implémenter la méthode equals(...) des objets que vous ajoutez dans un Set, car en l'absence de cette méthode, le Set n'utilisera que l'égalité par référence (==) pour des objets afin de tester l'égalité ou non de deux objets.
Pour créer un Set
Set<User> users = new HashSet<>();
Set<Value> values = new LinkedHashSet<>();
Set<Role> roles = new TreeSet<>();
Pour ajouter un élément
Il faut utiliser la méthode add(...)
users.add(new User("Java", "TutorialsHub"));
values.add(new Value(100_000_000d, 200_000d));
roles.add(new Role(1L, "admin", "Administrator"));
Pour récupérer un élément
Les éléments dans un Set ne sont pas directement accessibles par index, comme c'est le cas avec les list. Afin d'accéder aux éléments d'un Set, il faut utiliser l'Iterator sous-jacent.
Iterator<User> userIterator = users.iterator();
if(userIterator.hasNext()) {
User user = userIterator.next();
}
Iterator<Value> valueIterator = values.iterator();
if(valueIterator.hasNext()) {
Value value = valueIterator.next();
}
Iterator<Role> roleIterator = roles.iterator();
if(roleIterator.hasNext()) {
Role role = roleIterator.next();
}
Pour supprimer un élément
Il faut utiliser la méthode remove(...) en indiquant l'objet à supprimer (la référence de l'objet à supprimer)
users.remove(user);
values.remove(value);
roles.remove(role);
Récupérer la taille
La méthode size() est utilisée pour récupérer la taille d'un Set
int size = values.size();
Tester si la collection est vide
Comme pour les listes, la méthode isEmpty() permet de savoir si une liste est vide ou non. Et de même lorsque la valeur retournée par cette méthode est: true, cela signifie que le Set est vide. Dans le cas contraire , le Set contient au moins un élément.
if(roles.isEmpty()) {
}
4. Les Queue
Une queue est une collection en plus de présenter toutes les opérations communes aux collection en présente une version supplémentaire pour l'insertion, la suppression et la récupération des éléments. Une autre particularité des Queues est que les éléments sont accessibles selon la règle FIFO (First In First Out) autrement dit: Le premier inséré dans la queue est le premier qui en sortira. L'interface java.util.Queue est implémentée par plusieurs classes telles que: ArrayBlockingQueue, PriorityQueue, PriorityBlockingQueue et bien d'autres.
- Toujours utiliser une ArrayBlockingQueue, si vous souhaitez définir une queue avec une taille limitée: Tout ajout d'éléments dans la queue lorsque cette dernière est pleine lèvera une exception ou retournera la valeur: false, indiquant que l'ajout a échoué. Les méthodes de cette implémentation sont bloquantes.
- Toujours utiliser une PriorityQueue, si vous souhaitez que les éléments insérés dans la queue soient ordonnés selon un ordre particulier. Les éléments sont alors ordonnés selon l'ordre naturel ou selon le comparator indiqué lors de la création de la queue. Tous les éléments ajoutés dans cette queue doivent implémenter l'interface Comparable.
- La PriorityBlockingQueue est pareille que la PriorityQueue, à la seule différence qu'elle présente des méthodes bloquantes.
L'intérêt d'utiliser une queue réside dans le fait qu'une telle collection possède deux extrémités. Une extrémité pour l'ajout et une extrémité pour la lecture. En d'autres termes, pendant qu'un processus s'occupe de produire des éléments dans la queue, un autre processus a la possibilité de lire des éléments de la queue en la vidant progressivement par la même occasion.
Pour créer une queue
Queue<User> users = new ArrayBlockingQueue<>(10);
Queue<Value> values = new PriorityQueue<>();
Queue<Role> roles = new PriorityBlockingQueue<>();
Pour ajouter un élément
Deux méthodes sont disponibles pour ajouter un élément dans une queue. La méthode add(...) qui lèvera une exception en cas d'incapacité d'ajouter un élément et la méthode offer(...) qui retournera: false, si l'ajout a échoué.
users.add(new User("Java", "TutorialsHub"));
users.offer(new User("Java2", "TutorialsHub2"));
values.add(new Value(100_000_000d, 200_000d));
values.offer(new Value(100_000d, 200d));
roles.add(new Role(1L, "admin", "Administrator"));
roles.offer(new Role(2L, "admin", "Administrator"));
Pour récupérer un élément et le supprimer de la queue
Comme indiqué précédemment, une queue dispose de deux extrémité. La méthode naturelle pour la récupération des données dans une queue est celle qui consiste de récupérer l'objet en tête de queue et de le retirer de la queue. Il s'agit donc de la méthode poll().
User user = users.poll();
Value value = values.poll();
Role role = roles.poll();
Pour récupérer un élément et le conserver dans la queue
Si le besoin consiste à récupérer l'élément en tête de queue et de le conserver dans la queue, il faudra alors utiliser la méthode peek() à cet effet.
User user = users.peek();
Value value = values.peek();
Role role = roles.peek();
Pour supprimer un élément
Comme indiqué précédemment, la méthode poll() qui permet de lire l'élément en tête de queue, permet par la même occasion de le supprimer de la queue. Il existe également la méthode remove qui peut être utilisé pour enlever directement un objet de la queue.
users.remove(user);
values.remove(value);
roles.remove(role);
Récupérer la taille
La taille d'une queue peut être lue, comme pour toutes les autres collections, à l'aide de la méthode size()
int size = users.size();
Tester si la collection est vide
à l'instar de toutes les autres collections, on peut savoir si une queue est vide grace à la méthode isEmpty() comme suit:
if(roles.isEmpty()) {
}
5. Les Deque
Un deque est une queue qui dispose de deux extrémités. Le début et la fin. Cela signifie qu'on peut accéder aux éléments dans le deque soit en passant par le début soit en y accédant par la fin. Et vu que c'est une queue qui dispose de deux extrémités, alors on peut y insérer des éléments au début ou à la fin de cette collection. L'interface java.util.Deque est implémentée par plusieurs classes telles que: ArrayDeque, LinkedBlockingDeque et bien d'autres.
Note: Un deque peut être utilisée comme une queue. Dans ce cas, la récupération et l'ajout d'un élément dans le deque suivra la stratégie FIFO (First In First Out).
- Toujours utiliser un ArrayDeque lorsque vous êtes dans un contexte non multithreadé. Ce deque s'appuyant sur un tableau peut s'avérer extrêmement rapide comparé à une LinkedList ou un Stack.
- La LinkedBlockingDeque est comparable à une ArrayDeque sauf qu'elle est utilisable dans un contexte multithreadé et également propose des méthode bloquante.
Pour créer un deque
Deque<User> users = new ArrayDeque<>();
Deque<Value> values = new LinkedBlockingDeque<>();
Pour ajouter un élément à la fin du deque
Les méthodes add(...), offer(...), addLast(...) et offerLast(...) permettent d'ajouter un élément à la fin du deque comme suit:
users.add(new User("Java", "TutorialsHub"));
users.offer(new User("Java2", "TutorialsHub2"));
values.addLast(new Value(100_000_000d, 200_000d));
values.offerLast(new Value(100_000d, 200d));
Pour ajouter un élément au début du deque
Les méthodes addFirst(...) et offerFirst(...) permettent d'ajouter un élément au début du deque comme suit:
users.addFirst(new User("Java", "TutorialsHub"));
values.offerFirst(new Value(100_000d, 200d));
Pour récupérer un élément au début du deque et le supprimer du deque
Les méthodes poll(...) et pollFirst(...) permettent de récupérer le premier élément du deque et le supprimer du deque comme suit:
User user = users.poll();
Value value = values.pollFirst();
Pour récupérer un élément à la fin du deque et le supprimer du deque
La méthode pollLast(...) permet de récupérer le dernier élément du deque et le supprimer du deque comme suit:
User user = users.pollLast();
Value value = values.pollLast();
Pour récupérer un élément au début du deque et le conserver dans le deque
Les méthodes peek(...) et peekFirst(...) permettent de récupérer le premier élément du deque et ne le supprime pas du deque comme suit:
User user = users.peek();
Value value = values.peekFirst();
Pour récupérer un élément à la fin du deque et le conserver dans le deque
La méthode peekLast(...) permet de récupérer le dernier élément du deque et ne le supprime pas du deque comme suit:
User user = users.peekLast();
Value value = values.peekLast();
Pour supprimer un élément
La méthode poll(...) et pollFirst(...) commet indiqué précédemment, permettent de récupérer mais aussi de supprimer le premier élément du deque.
Quant à la méthode pollLast(...), elle permet de récupérer mais aussi de supprimer un élément à la fin du deque.
Les méthodes remove(...) et removeFirst(...) permettent de supprimer un élément au début du deque comme suit:
users.remove();
values.removeFirst();
Afin de supprimer un élément à la fin du deque, il faut utiliser la méthode removeLast(...):
users.removeLast();
values.removeLast();
Il est aussi possible de supprimer un objet du deue en l'indiquant en paramètre de la méthode remove(...)
users.remove(user);
Récupérer la taille
A l'instar de toutes les collections en Java, il faut utiliser la méthode size() pour récupérer la taille de la collection comme suit:
int size = users.size();
Tester si la collection est vide
Encore une fois, et comme pour toutes les autres collections, la méthode isEmpty() permet de savoir si le deque est vide ou non.
if(values.isEmpty()) {
}
Le code source de ce tutoriel est présent sur github à cette adresse:java-collections
Ne pas hésiter à commenter ou à poser une question ou à demander de l'aide autours de java et des technologies connexes. Nous nous ferons un plaisir de vous répondre.
Commentaires
Enregistrer un commentaire