Résumé Big-O pour les implémentations de Java Collections Framework? [fermé]


164

J'enseignerai peut-être bientôt un "cours intensif Java". Bien qu'il soit probablement sûr de supposer que les membres du public connaîtront la notation Big-O, il n'est probablement pas sûr de supposer qu'ils sauront quel est l'ordre des différentes opérations sur diverses implémentations de collection.

Je pourrais prendre le temps de générer moi-même une matrice récapitulative, mais si elle est déjà quelque part dans le domaine public, j'aimerais bien la réutiliser (avec le crédit approprié, bien sûr).

Quelqu'un a des pointeurs?


Voici un lien que j'ai trouvé utile lors de la discussion de certains objets Java très courants et du coût de leurs opérations en utilisant la notation Big-O. objectissues.blogspot.com/2006/11/…
Nick

Bien que n'étant pas dans le domaine public, les excellents Java Generics and Collections de Maurice Naftalin et Philip Wadler répertorient des aperçus des informations d'exécution dans ses chapitres sur les différentes classes de collection.
Fabian Steeg

1
Cette référence de performance serait-elle utile?
ThreaT

Réponses:


149

Ce site Web est assez bon mais pas spécifique à Java: http://bigocheatsheet.com/ Voici une image au cas où ce lien ne fonctionnerait pas


27
Et c'est pourquoi nous n'utilisons pas les URL comme réponses. Ce document / serveur, pour autant que je sache, n'est plus disponible!
Jason Mock

1
@Ben J Links ne fonctionnent plus
Vikas V

Les liens des archives Web sont désormais également rompus.
MikeFHay

Semble de nouvelles URL de travail ajoutées. Merci d'avoir fait l'effort, c'est très utile.
Tejas C

1
@AndreaZilio LinkedList.remove (Object) est un temps constant, en supposant que vous connaissez déjà le voisin. Si vous ne connaissez pas le voisin, il est temps de le trouver en premier.
Paul Evans

217

Le livre Java Generics and Collections contient ces informations (pages: 188, 211, 222, 240).

Répertorier les implémentations:

                      get  add  contains next remove(0) iterator.remove
ArrayList             O(1) O(1) O(n)     O(1) O(n)      O(n)
LinkedList            O(n) O(1) O(n)     O(1) O(1)      O(1)
CopyOnWrite-ArrayList O(1) O(n) O(n)     O(1) O(n)      O(n)

Définir les implémentations:

                      add      contains next     notes
HashSet               O(1)     O(1)     O(h/n)   h is the table capacity
LinkedHashSet         O(1)     O(1)     O(1) 
CopyOnWriteArraySet   O(n)     O(n)     O(1) 
EnumSet               O(1)     O(1)     O(1) 
TreeSet               O(log n) O(log n) O(log n)
ConcurrentSkipListSet O(log n) O(log n) O(1)

Implémentations de la carte:

                      get      containsKey next     Notes
HashMap               O(1)     O(1)        O(h/n)   h is the table capacity
LinkedHashMap         O(1)     O(1)        O(1) 
IdentityHashMap       O(1)     O(1)        O(h/n)   h is the table capacity 
EnumMap               O(1)     O(1)        O(1) 
TreeMap               O(log n) O(log n)    O(log n) 
ConcurrentHashMap     O(1)     O(1)        O(h/n)   h is the table capacity 
ConcurrentSkipListMap O(log n) O(log n)    O(1)

Implémentations de file d'attente:

                      offer    peek poll     size
PriorityQueue         O(log n) O(1) O(log n) O(1)
ConcurrentLinkedQueue O(1)     O(1) O(1)     O(n)
ArrayBlockingQueue    O(1)     O(1) O(1)     O(1)
LinkedBlockingQueue   O(1)     O(1) O(1)     O(1)
PriorityBlockingQueue O(log n) O(1) O(log n) O(1)
DelayQueue            O(log n) O(1) O(log n) O(1)
LinkedList            O(1)     O(1) O(1)     O(1)
ArrayDeque            O(1)     O(1) O(1)     O(1)
LinkedBlockingDeque   O(1)     O(1) O(1)     O(1)

Le bas du javadoc pour le package java.util contient quelques bons liens:


3
Vous devez spécifier pour quel scénario de cas sont ces chiffres, par exemple, la suppression de Arraylist pourrait prendre O (n), si vous supprimez l'élément au milieu ou à la fin du tableau.
Popeye

@popeye n'est généralement pas le pire des cas?
Yassin Hajaj

Comme mentionné par @Popeye, il devrait y avoir une description claire du cas sur lequel porte la réponse. Le cas peut être soit moyen / pire pour la complexité temporelle. Il semble que la réponse se réfère à un cas "moyen" pour tous les DS.
Yashwin Munsadwala

12

Les Javadocs de Sun pour chaque classe de collection vous diront généralement exactement ce que vous voulez. HashMap , par exemple:

Cette implémentation fournit des performances à temps constant pour les opérations de base (get et put), en supposant que la fonction de hachage répartit correctement les éléments entre les compartiments. L'itération sur les vues de collection nécessite un temps proportionnel à la «capacité» de l'instance HashMap (le nombre de compartiments) plus sa taille (le nombre de mappages clé-valeur).

TreeMap :

Cette implémentation fournit un coût en temps log (n) garanti pour les opérations containsKey, get, put et remove.

TreeSet :

Cette implémentation offre un coût en temps log (n) garanti pour les opérations de base (ajouter, supprimer et contient).

(c'est moi qui souligne)


Je ne suis pas d'accord avec la partie HashMap. Je connais la position de Sun, mais ... get par exemple doit appeler obj.equals (key), qui pourrait être linéaire dans la taille des objets contenus. Considérez que vous devez généralement lire les champs pour cette comparaison. Les exceptions seraient des entiers ou des chaînes (internes) ???
Survolé le

Tout d'abord, s'ils se sont trompés, il ne devrait pas être trop difficile pour vous de créer un scénario de test qui réfute les performances à temps constant? Deuxièmement, si vous regardez le code source de HashMap, il n'appelle pas equals () pour chaque clé de la carte - uniquement lorsque les codes de hachage sont égaux.
matt b

5
Si vous lisez la citation ci-dessus, elle dit que c'est un temps constant "en supposant que la fonction de hachage répartit correctement les éléments entre les compartiments". D'après la théorie CS, les tables de hachage ont des opérations à temps constant lorsque la fonction de hachage est "bonne" (ce qui se produit en moyenne), mais peuvent prendre un temps linéaire dans le pire des cas.
newacct

4
@Overflown - techniquement, peu importe combien de temps obj.equals () prend du point de vue de la complexité, car cela fait simplement partie de la "constante" par rapport au nombre d'éléments dans la collection.
mikera

6

Le gars ci-dessus a donné une comparaison pour HashMap / HashSet vs TreeMap / TreeSet.

Je vais parler d'ArrayList vs LinkedList:

Liste des tableaux:

  • O (1) get()
  • amorti O (1) add()
  • si vous insérez ou supprimez un élément au milieu en utilisant ListIterator.add()ou Iterator.remove(), ce sera O (n) pour décaler tous les éléments suivants

LinkedList:

  • Sur) get()
  • O (1) add()
  • si vous insérez ou supprimez un élément au milieu en utilisant ListIterator.add()ou Iterator.remove(), ce sera O (1)

1
if you insert or delete an element in the middle using ListIterator.add() or Iterator.remove(), it will be O(1) Pourquoi? nous devons d'abord trouver l'élément au milieu, alors pourquoi ce n'est pas O (n)?
MyTitle

@MyTitle: relisez-le. "using ListIterator.add()or Iterator.remove()" Nous avons un itérateur.
newacct
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.