2010-07-26 5 views
1

Pourquoi Set.size() ne correspond-il pas au nombre d'éléments dans l'itérateur de l'ensemble? J'utilise un HashSet et j'ai ajouté quelques valeurs en double. Ces doublons ont été automatiquement éliminés depuis que j'ai utilisé un ensemble. Set.size() renvoie 16. Lorsque je itère réellement sur les éléments, j'en ai 13. 13.Set.size() ne correspond pas au nombre d'éléments dans l'itérateur

Quelle peut être la cause de cette différence? Est-ce que je le fais bien?

Set set = new HashSet(); 
... 
System.out.println ("Found " + set.size() + " tokens..."); 
Iterator it = set.iterator(); 
int i = 0; 
while (it.hasNext()) { 
    i++; 
    System.out.println(Integer.toString(i) + ": " + (String)it.next()); 
} 

est ici la sortie de la console:

Found 16 tokens... 
1: 3 Months Free HD Extra Pack 
2: Best Buy - $30 for 3 Months (Instant Rebate) 
3: Gift Card - Fry's - $100 (HDTV Offer) 
4: 6 Months FREE Showtime 
5: 3 Months Free HD Access 
6: Savings Certificate Booklet 
7: 3 months FREE Showtime (rolls off month 4) 
8: Free NASCAR Hotpass 
9: 3 Months Free DVR Service 
10: $0 Delivery & Handling 
11: 1 Year Free Showtime 
12: $99 Off Advance Equipment (2nd AP) 
13: Best Buy - $30 for 12 Months (Instant Rebate) 
+7

Veuillez montrer un programme court mais * complet * qui démontre le problème. Je viens d'essayer mais je n'ai pas réussi à le reproduire. –

+3

En d'autres termes, publiez un [SSCCE] (http://sscce.org) afin que nous puissions le copier et le copier sans le moindre changement de code. – BalusC

+4

Est-ce que n'importe quel autre thread a accès au HashSet? –

Répondre

3

Sérieusement, ce n'est pas possible. HashSet est une classe assez bien établie qu'il n'y a pas de possibilité d'un bug comme vous l'avez décrit. Voici quelques façons de rendre cela possible:

  • Visser avec l'ensemble en utilisant Reflection comme Mark Peters suggère;
  • Vous avez fait une exception à être jeté après le 13 élément qui met fin au programme
  • Outrepasser le comportement de Set à la rendre incompatible
  • Vous utilisez des jeux différents pour l'impression du total et les articles
+0

Après le déjeuner, je ne pouvais pas reproduire le même problème. Mon code était très simple, et ma seule supposition est que j'avais juste quelques problèmes de défilement vers le bas de la sortie. Comme vous pouvez le voir à partir de mon extrait de sortie ci-dessus, je n'ai jamais eu de marqueur pour la fin de la sortie - donc je ne serai jamais sûr - mais je me range du côté de votre théorie qu'il s'agissait d'une erreur utilisateur. Merci. –

+1

une autre possibilité: votre ensemble pourrait contenir un élément 'null' (HashSets peut contenir au plus un élément 'null' dans l'ensemble). Certains débogueurs n'affichent pas l'élément 'null' de sorte que lorsque vous comparez la taille de la liste et les éléments, vous voyez un certain listSize mais ne voyez que les éléments listSize-1 lors de l'inspection de la liste. – Pierre

3

Parce que vous avez utilisé la réflexion:

Set set = new HashSet(); 

Field size = HashMap.class.getDeclaredField("size"); 
size.setAccessible(true); 
Field map = HashSet.class.getDeclaredField("map"); 
map.setAccessible(true); 
size.set(map.get(set), 16); 

System.out.println("Found " + set.size() + " tokens..."); 

Sérieusement, c'est la seule façon que je peux penser à vous que vous obtiendriez ces résultats, en supposant que vous utilisez le HashSet standard et non un tiers. Maintenant, je ne peux pas imaginer que vous seriez en train d'utiliser la réflexion pour le faire et je ne comprendrais pas vos résultats, donc je suppose que vous vous trompez dans quelque chose que vous nous dites (par exemple, l'ensemble n'est pas local mais accessible par un autre thread).

+0

Ouais, ça l'aurait fait - mais ce n'est pas ce que j'ai fait. Merci de m'avoir appris une nouvelle façon de botcher mes programmes. Je suis sûr que je vais l'utiliser de manière inappropriée un jour;) –

Questions connexes