Je souhaite connaître la comparaison entre List et Set en termes de performances, d’allocation de mémoire et de convivialité.
Si je ne souhaite pas conserver l'unicité dans la liste des objets, ni que l'ordre d'insertion soit maintenu, puis-je utiliser indifféremment ArrayList et SortedSet/HashSet? de même liste/set?
P.S. De plus, je n'ai pas besoin de liste ni de fonctions spécifiques fournies par Java ..___. J'utilise List/Set au lieu de Array uniquement parce qu'elles peuvent croître de manière dynamique sans efforts de programmation supplémentaires.
Si vous ne vous souciez pas de l'ordre et que vous ne supprimez pas les éléments, vous devez savoir si vous devez rechercher des éléments dans cette structure de données et la rapidité avec laquelle vous avez besoin de ces recherches.
Trouver un élément par valeur dans une HashSet
est O(1)
. Dans une ArrayList
, c'est O(n)
.
Si vous n'utilisez le conteneur que pour stocker une série d'objets uniques et que vous les parcourez à la fin (dans n'importe quel ordre), alors ArrayList
est sans doute un meilleur choix car il est plus simple et plus économique.
HashSet
consomme environ 5,5 fois plus de mémoire que ArrayList
pour le même nombre d'éléments (bien qu'ils soient tous les deux linéaires), et son itération est beaucoup plus lente (bien qu'avec les mêmes asymptotiques); une recherche rapide dans Google suggère un ralentissement de 2 à 3 fois pour l'itération HashSet
par rapport à ArrayList
.
Si vous ne vous souciez pas de l'unicité ou des performances de contains
, utilisez ArrayList
.
Si vous envisagez uniquement d'ajouter des éléments et de les parcourir plus tard, votre meilleur choix est ArrayList
car il se rapproche le plus des tableaux que vous remplacez. La mémoire est plus efficace que LinkedList
ou n’importe quelle implémentation Set
, elle a une insertion rapide, une itération et un accès aléatoire.
Utilisez HashSet
si vous devez utiliser .contains(T)
fréquemment.
Exemple:
private static final HashSet<String> KEYWORDS = Stream.of(new String[]{"if", "do", "for", "try", "while", "break", "return"}).collect(Collectors.toCollection(HashSet::new));
public boolean isKeyword(String str) {
return KEYWORDS.contains(str);
}
Si vous comparez, la recherche entre List et Set, Set sera meilleure en raison de l'algorithme de hachage souligné.
Dans le cas d’une liste, dans le pire des cas, contient cherchera jusqu’à la fin . Dans le cas de Set, à cause du hachage et du bucket, il ne cherchera qu’un sous-ensemble.
Exemple de cas d'utilisation: Ajoutez 1 à 100_000 entiers à ArrayList et à HashSet . Recherchez chaque entier dans ArrayList et HashSet.
L'ensemble prendra 9 millisecondes et, en tant que liste, 16232 secondes.
private static void compareSetvsList(){
List<Integer> list = new ArrayList<>() ;
Set<Integer> set = new HashSet<>() ;
System.out.println("Setting values in list and set .... ");
int counter = 100_000 ;
for(int i =0 ; i< counter ; i++){
list.add(i);
set.add(i);
}
System.out.println("Checking time .... ");
long l1 = System.currentTimeMillis();
for(int i =0 ; i< counter ; i++) list.contains(i);
long l2 = System.currentTimeMillis();
System.out.println(" time taken for list : "+ (l2-l1));
for(int i =0 ; i< counter ; i++)set.contains(i);
long l3 = System.currentTimeMillis();
System.out.println(" time taken for set : "+ (l3-l2));
// for 10000 time taken for list : 123 time taken for set : 4
// for 100000 time taken for list : 16232 time taken for set : 9
// for 1000000 time taken for list : hung time taken for set : 26
}
Si vous n'avez pas besoin d'avoir des éléments uniques dans collection , utilisez simplement ArrayList
à moins que vous n'ayez des besoins très spécifiques.
Si vous avez uniquement besoin d’éléments uniques dans collection , utilisez HashSet
sauf si vous avez des besoins très spécifiques.
Concernant SortedSet
(et son implémentateur TreeSet
), selon JavaDoc:
Un ensemble qui fournit en outre un ordre total sur ses éléments. Les éléments sont ordonnés en utilisant leur ordre naturel ou par un comparateur généralement fourni au moment de la création du jeu trié.
Cela signifie qu'il est destiné à des cas d'utilisation très spécifiques, où les éléments doivent toujours être ordonnés dans une set
, ce qui n'est généralement pas nécessaire.