HashSet Java avec des critères d'égalité personnalisés? [dupliquer]

cette question a déjà une réponse ici:

je cherchais quelque chose qui s'apparente à la capacité du Java TreeSet de recevoir un comparateur personnalisé à instanciation time, donc je n'avais pas besoin d'utiliser les critères d'égalité par défaut (et de hachage du code) de l'objet.

le plus proche que j'ai pu trouver était d'envelopper mes objets dans une classe personnalisée privée, mais cela semble hacky :( cela finit par être une sorte de thème récurrent lors de la programmation, donc je me demandais s'il ya quelque chose déjà disponible pour nous d'utiliser. Peut-être dans les bibliothèques communes?

Merci

26
demandé sur devoured elysium 2013-02-14 21:19:46

3 réponses

Non, vous avez trouvé exactement la solution que vous êtes censé utiliser.

même pour TreeSet , c'est mal vu sur d'utiliser des critères de comparaison qui ne sont pas compatibles avec equals :

noter que l'ordre maintenu par un ensemble trié (qu'un comparateur explicite soit fourni ou non) doit être compatible avec equals si l'ensemble trié doit implémenter correctement l'interface Set.

(Je ne sais pas pour Apache Commons, mais Guava spécifiquement rejeté demandes pour ce genre de chose.)

12
répondu Louis Wasserman 2013-02-14 17:25:55

vous avez raison, quand vous voulez utiliser l'un des Trees ( TreeMap , TreeSet ) les objets que vous ajoutez doivent implémenter Comparable .

pour les types primitifs, Java a résolu ceci pour vous.

Pour les objets personnalisés vous avez 3 possibilités:

  1. L'un de vos objets possède déjà un identifiant unique de type primitif ou Type qui met déjà en œuvre compareTo() (comme String ) Alors utilisez ce champ pour compareTo, si les valeurs des autres ne sont pas importants pour l'égalité. (Mais alors equals() doit également utiliser ce seul champ)

  2. Utiliser EqualsBuilder d'Apache: Cela fonctionne avec la réflexion, et n'est pas la solution la plus rapide

  3. écrivez-le vous-même, lisez quelques tutoriels comment le faire: E. g:

Josh Bloch: Effective java 2nd Edition

mais n'oubliez pas que equals() , et compareTo() doivent être compatibles (et hashCode() , aussi), de sorte que vous ne violez pas le contrat égal. (Le contrat lui-même est moins compréhensible, mais il devient clair si vous foillow l'un de cela égale des tutoriels.)

ou Oubliez tout cela, et utilisez un HashSet , HashMap .

3
répondu AlexWien 2013-06-01 16:30:57

il y a quelques cadres de recouvrement tiers qui permettent la logique d'égalité personnalisée. C'est parfait pour remplacer l'égalité pour les objets que vous ne pouvez pas modifier la source.

les cartes/décors de Trove supportent l'utilisation de stratégies de hachage personnalisées, vous permettant d'accorder les collections en fonction des caractéristiques de l'entrée données. Cette fonctionnalité vous permet également de définir les fonctions de hachage quand il est impossible d'outrepasser L'objet.hashCode ().

pour y parvenir, tout type qui nécessite une correction standard, doit mettre en œuvre l'interface HE-Collection equals Andhcorrection. Ce interface définit les méthodes hashCodeInHeCollection () et equalsInHeCollection (Object), qui servent de correction pour le méthodes incorrectes implémentées hashCode () et equals (Object).

2
répondu Steve Kuo 2013-02-14 18:11:32