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
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.)
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:
-
L'un de vos objets possède déjà un identifiant unique de type primitif ou Type qui met déjà en œuvre
compareTo()
(commeString
) Alors utilisez ce champ pour compareTo, si les valeurs des autres ne sont pas importants pour l'égalité. (Mais alorsequals()
doit également utiliser ce seul champ) -
Utiliser
EqualsBuilder
d'Apache: Cela fonctionne avec la réflexion, et n'est pas la solution la plus rapide -
é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
.
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).