2010-12-14 31 views
2

En Java 6, je crois comprendre que vous pouvez fournir un comparateur à un TreeSet lors de sa création pour remplacer l'ordre naturel des objets dans l'ensemble. Avez-vous des idées pour lesquelles Java ne supporte pas la fourniture d'un "hachage" qui outrepasse le "hachage naturel" des objets de l'ensemble?Pourquoi pouvons-nous fournir un comparateur à TreeSet mais pas quelque chose comme Hasher à HashSet?

EDIT: Obtenir des commentaires de votre part pourrait m'aider lors de la conception d'API dans le futur.

Merci.

+1

L'API est ce qu'elle est. Demander "pourquoi" ne peut être que spéculation. – skaffman

+1

Vous pourriez poser la même question à Set and equal. – Ralph

+0

+1 @Ralph, spirituel! – Russell

Répondre

2

Voici plusieurs raisons probables:

  • Simplicité - la plupart des gens ne ont pas besoin de multiples fonctions de hachage, afin de garder l'API simple, il est logique de compter sur un seul objet.approche hashCode()

  • Performance - Dans la bibliothèque standard au moins, HashSet et HashMaps etc. doivent être assez fortement optimisé car ils sont si largement utilisée. Il n'a pas de sens d'avoir le surcoût d'appeler un séparé "hasher", si petit que peut être.

  • champs privés - il y a la question que hashCode() peut compter sur privé des champs, il peut être difficile de créer « hashers » externes pour certains objets.

1

C'est le cas! Découvrez la méthode Object.hashCode. Après avoir relu votre question, j'ai peut-être sauté le pistolet. Je vois maintenant que vous avez dit "remplacer" le hshing naturel. Habituellement, nous remplaçons la valeur de hachage au niveau de l'objet et renonçons à l'utilisation d'un hachage remplaçant.

Les hachages sont destinés à être plus universels que les comparateurs. Autrement dit, les hachages devraient presque toujours créer des valeurs douteuses uniformes avec peu de chance de collision. Le conteneur dans lequel ils sont utilisés devrait rarement avoir besoin d'un hachage spécialisé.

+0

Vous êtes revenu pour répondre à la question! +1 pour cela :) – Russell

2

Un objet Hasher serait redondant de la méthode dans la classe hashCode()Object.

Si vous voulez effectuer la nature du hachage, vous devez remplacer la méthode hashCode() définie sur Object. Assurez-vous de surcharger equals(Object), car ces deux devraient toujours aller ensemble.

Un HashSet ou une autre structure de données similaire utilisera la méthode Objets hashCode() pour obtenir une valeur de hachage pour déterminer le stockage de la corbeille. Il utilisera ensuite equals() pour comparer cet objet à d'autres objets de la même corbeille pour déterminer l'égalité.

Le code de hachage généré doit être unique à cette classe d'objet spécifique. Cela peut être assuré simplement en remplaçant la méthode hashCode() et n'a pas besoin de passer de l'implémentation à l'implémentation. Un objet Hasher ne ferait qu'obscurcir et ne servirait à rien d'autre. Je ne pouvais pas penser à un seul cas d'utilisation où plusieurs codes de hachage seraient nécessaires pour le stockage dans différentes structures de données.

+0

Absolument correct, et votre contribution à pourquoi il y a un comparateur et pas un hacher est? – Russell

+0

Vous n'avez pas besoin de 'Hasher' quand il y a une méthode' hashCode() 'sur Object qui le fait déjà. Si 'Object' avait une méthode' compareTo() ', alors vous n'auriez pas besoin de' Comparator'. –

+0

Vous avez besoin d'un comparateur si vous voulez remplacer l'ordre naturel, mais je vois d'où vous venez. Merci! – Russell

0

Vous pouvez modifier le code de hachage d'un objet en l'enveloppant dans un objet qui code le code de hachage à votre façon. L'hypothèse est que vous voudrez peut-être trier un certain nombre d'objets, mais ne pas avoir plusieurs stratégies de hachage.

c.f. Trove4j supporte les stratégies de hachage pour son HashMap et bien que j'utilise souvent cette bibliothèque, je n'ai utilisé une stratégie de hachage personnalisée qu'une fois que je me souviens.