2009-06-30 8 views
-1
Set<Type> union = new HashSet<Type>(s1); 
union.addAll(s2); 

ETest-il une différence entre ces deux groupes de déclarations

Set <Type> union = new HashSet<Type>(); 
union.addAll(s1); 
union.addAll(s2); 
+0

cette question a été posée à deux reprises avant: http://stackoverflow.com/questions/1058331/what-is-the-exact-difference-between-these-two-groups-of-statements-closed et http: //stackoverflow.com/questions/1058205/what-is-the-exact-difference-between-these-two-groups-of-statements – akf

+0

veuillez expliquer ces choses logiquement et par programme – Johanna

+0

regardez ce lien: http: // java .sun.com/docs/books/tutorial/collections/interfaces/set.html et dans la partie de l'opération en bloc, vous pouvez voir qu'il est écrit: Pour calculer l'union, intersection, ou définir la différence de deux ensembles non destructive (sans modifier ensemble), l'appelant doit copier un ensemble avant d'appeler l'opération en bloc appropriée. Ce qui suit sont les idiomes résultant. donc il devrait y avoir une différence entre ces deux groupes d'instructions. – Johanna

Répondre

2

La différence ici est beaucoup moins que votre question précédente.
La première voie devrait être plus rapide car le Set original n'aura pas à grandir autant.

La façon dont vous pouvez faire est:

Set<Type> union = new HashSet<Type>(s1.size() + s2.size()); 
union.addAll(s1); 
union.addAll(s2); 

De cette façon, vous n'aurez pas à redimensionner tout nouveau Set. (Même si vous pouvez avoir un peu d'espace supplémentaire)

1

ou logiquement Programmatically?

Cause à la fin vous finissez avec la même collection.

0

La première version pourrait être un peu plus efficace, car elle alloue assez d'espace pour contenir les éléments de s1.

1

Je voudrais aller avec la deuxième forme, car il est plus clair à lire. Il est plus facile de voir que cela ajoute deux choses à l'ensemble parce qu'il est explicite. Utiliser deux manières différentes de mettre des choses dans l'ensemble obscurcit le fait que la même opération est faite deux fois.

0

À partir du code source Java 6, nous pouvons voir que le constructeur appelle en fait addAll une fois initialisés la taille des ensembles:

public HashSet(Collection<? extends E> c) { 
    map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16)); 
    addAll(c); 
} 

Notez que cela ajoute au moins un tiers la capacité supplémentaire, donc peut-être assez bon si s2 est petit ou si vous attendez un bon nombre de valeurs croisées dans les deux ensembles. Dans le cas contraire, toutes les autres réponses ont un sens!

0

Cela dépend de la taille de vos deux ensembles.

(Méthode 1)
La première est de dire:

Set union = new HashSet(); 
union.addAll(s1); 
union.addAll(s2); 

Cela nécessite 3 déclarations, et n'est pas garanti d'être d'abord assez grand pour contenir tous vos éléments. Le magasin de sauvegarde par défaut est 16 éléments. Si vous avez plus de 16 éléments entre s1 et s2, appeler le constructeur sans paramètres sera moins efficace, car il devra créer un nouveau backing store suffisamment grand pour contenir à la fois s1 et s2.

(Méthode 2)
Si vous dites:

Set union = new HashSet(s1.size() + s2.size()); 
union.addAll(s1); 
union.addAll(s2); 

Vous serez assuré d'avoir un ensemble qui contiendra tous vos articles, mais il faut aussi 3 déclarations.

(Méthode 3)
Si vous créez un nouveau HashSet avec un ensemble, il alloue deux fois la taille de cet ensemble. (Java api link) Donc, si s1 est plus grand que s2, vous obtenez le même effet en disant:

Set union = new HashSet(s1); 
union.addAll(s2); 

Et vous ne avez besoin de 2 déclarations.

Si vous savez à l'avance quel jeu sera le plus grand, utilisez la méthode n ° 3, mais si ce n'est pas le cas, utilisez la méthode n ° 2.

+0

La déclaration sur l'allocation de collection pour doubler la taille de HashSet n'est vraie que pour Java version 1.3.1 et plus ancienne. Si vous utilisez la version 1.4.2 ou plus récente, la méthode n ° 2 est probablement la meilleure dans la plupart des situations. –

Questions connexes