6
votes

Un ensemble dans Java ne permet jamais des doublons, mais il faut des objets StressBuffer avec le même argument. Pourquoi?

[abc,abc,abc,abc]

4 commentaires

Stringbuffer ne écrase pas Equals () / Hashcode (), chaque instance Stringbuffer sera donc ajoutée à l'ensemble, quelle que soit le contenu de Stressbuffer.


@Proko Le hashcode () s'assure simplement qu'il regarde dans le godet droit pour l'article. C'est en fait la méthode égale () qui provoque des doublons. Il serait possible (bien que pas très performant) de créer une classe StringBuffer qui avait exactement le même hashcode, mais une égalité différente, et qu'ils seraient reconnus comme des individus aussi.


@Lunivore: Ouais je suis au courant de cela. Mais en regardant l'autre réponse ici, il semble familier de mentionner les deux méthodes de ce contexte.


@Proko Votre édition sur le commentaire le rend maintenant précis;)


6 Réponses :


1
votes

Vous avez eu lieu à vous de voir la méthode égale () (ou le manque de celui-ci) dans la Stringbuffer? Il y a la réponse pour vous.

Un ensemble ou pour cette affaire, toute collection basée sur le hachage dépend du contrat exposé par la méthode EQUALES () et HASHCODE () sur l'objet pour leur caractéristique de comportement.

Dans votre cas, car StressBuffer ne remplace pas ces méthodes que chaque instance StringBuffer que vous créez est différente I.e New Stringbuffer ("ABC") == New Stringbuffer ("abc") retournera false.

Je suis curieux de savoir pourquoi quelqu'un ajouterait Stringbuffer à un ensemble.


0 commentaires

13
votes

Stringbuffer ne remplace pas objet # égaux () et objet #cockode () , donc identité de Stringbuffer est basé pas sur le contenu du tampon, mais par l'adresse de l'objet en mémoire. *


* Cette identité est basée sur une adresse en mémoire n'est pas strictement requise par les JLS, mais est une conséquence d'un objet typique HashCode () implémentation. De Javadoc:

Autant que c'est raisonnablement pratique, la méthode de code HASHCODE définie par classe objet renvoie des entiers distincts pour des objets distincts. (Ceci est typiquement mis en œuvre en convertissant l'adresse interne de l'objet en un entier, mais cette technique de mise en œuvre n'est pas requise par le langage de programmation Java ™.)


0 commentaires

8
votes

stringbuffer ne remplace pas non plus égale ou hashcode - de sorte que chaque objet n'est que égal à lui-même.

Ceci est logique que Stringbuffer est très "mutable par conception" - et l'égalité peut causer des problèmes lorsque deux objets mutables sont égaux les uns aux autres, comme on peut alors changer. L'utilisation d'objets mutables sous forme de touches sur une carte ou une partie d'un ensemble peut causer des problèmes. Si vous militatez l'une après l'insertion dans la collection, cela invalide l'entrée dans la collection car le code de hachage est susceptible de changer. Par exemple, dans une carte, vous ne seriez même pas en mesure de rechercher la valeur avec l'objet même comme clé, comme le premier test est par code de hachage.

stringbuffer (et stringbuilder ) sont conçus pour être des objets très transitoires - Créez-les, appendez-les, convertissez-les en chaînes, puis vous avez terminé. Chaque fois que vous vous trouvez les ajouter aux collections, vous devez prendre un pas en arrière et voir s'il est vraiment logique. Juste occasionnellement cela pourrait faire, mais généralement uniquement lorsque la collection elle-même est courte.

Vous devez considérer cela dans votre propre code lorsque vous remplissez égal et hashcode - c'est très rarement une bonne idée d'égalité à être basée sur n'importe quel aspect mutable d'un objet; Il rend la classe plus difficile à utiliser correctement et peut facilement conduire à des bugs subtils qui peuvent prendre beaucoup de temps à déboguer.


1 commentaires

+1: Des objets mutables dans des ensembles (ou, plus généralement, car les clés de la carte) ne sont qu'une mauvaise idée. Lorsqu'une classe de bibliothèque standard ne remplace pas égale () et hashcode () , c'est un indice assez fort.



0
votes

Deux objets Stringbuffer sont différents objets malgré les mêmes arguments. Par conséquent, HashSet ajoute simplement les Stressbuffers au lieu d'ignorer les doublons.


0 commentaires

0
votes

Un jeu de hasch fonctionne avec des "godets". Il stocke des valeurs dans ces "godets" en fonction de leur code de hachage. Un "godet" peut y avoir plusieurs membres, selon que les membres sont égaux, à l'aide de la méthode égale (objet) .

Disons-nous que nous construisons un hachage ensemble avec 10 seaux, pour l'argument, et ajoutez les entiers 1, 2, 3, 5, 7, 11 et 13. Le code de hachage pour un int est juste l'int. Nous nous retrouvons avec quelque chose comme ça:

  • (vide)
  • 1, 11
  • 2
  • 3, 13
  • (vide)
  • 5
  • (vide)
  • 7
  • (vide)
  • (vide)

    La manière traditionnelle d'utiliser un ensemble consiste à regarder et à voir si un membre est dans cet ensemble. Alors, quand on dit: "Est 11 dans cet ensemble?" L'ensemble de hachage sera modulo 11 par 10, obtenez-en 1 et regardez dans le 2ème seau (nous commençons nos godets avec 0 bien sûr).

    Cela le rend vraiment, vraiment rapide de voir si les membres appartiennent à un ensemble ou non. Si nous ajoutons un autre 11, l'ensemble de hachage semble voir si c'est déjà là. Il ne l'ajoutera plus à nouveau si c'est. Il utilise la méthode égale (objet) pour déterminer cela, et bien sûr, 11 est égal à 11.

    Le code de hachage pour une chaîne comme "ABC" dépend des caractères de cette chaîne. Lorsque vous ajoutez une chaîne en double, "ABC", le jeu de hachage examinera dans le godet droit, puis utilisez la méthode égale (objet) pour voir si le membre est déjà là. Les Equals (objet) La méthode de chaîne dépend également des caractères, de sorte que "ABC" est égal à "ABC".

    Lorsque vous utilisez une StressBuffer, chaque stringbuffer dispose d'un code de hachage et d'une égalité basée sur son identifiant d'objet. Il ne remplace pas les éléments de base EQUALES (objet) et HashCode () méthodes, chaque stringbuffer se penche sur le hachage défini comme un objet différent. Ils ne sont pas réellement duplicats.

    Lorsque vous imprimez les Stringbufferers à la sortie, vous appelez la méthode Tostring () sur les Stringbuffers. Cela les fait ressembler à des cordes en double, c'est pourquoi vous voyez cette sortie.

    C'est aussi pourquoi il est très important de remplacer hashcode () si vous remplacez égaux (objet) , sinon l'ensemble regarde dans le mauvais godet et que vous en obtenez très Comportement impair et imprévisible!


0 commentaires

1
votes

L'objet le plus mutable ne suppose pas que s'ils contiennent les mêmes données, elles sont identiques. Comme ils sont mutables, vous pouvez modifier le contenu à tout moment. C'est-à-dire que cela pourrait être la même chose maintenant, mais pas plus tard, ou cela pourrait être différent maintenant, mais soyez le même plus tard

BTW Vous ne devriez pas utiliser Stringbuffer si StressBuilder est une option. Stringbuffer a été remplacé il y a plus de dix ans.


0 commentaires