web-dev-qa-db-fra.com

Comparaison des performances et de l'allocation de mémoire entre List et Set

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.

44
Priyank Doshi

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.

39
NPE

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.

65
Louis Wasserman

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.

1
Marko Topolnik

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);
}
0
Dave_cz

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

}
0
Manoj

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.

0
Yura