Existe-t-il un moyen de remplacer la méthode equals
utilisée par un type de données Set
? J'ai écrit une méthode equals
personnalisée pour une classe appelée Fee
. J'ai maintenant un LnkedList
de Fee
et je veux m'assurer qu'il n'y a pas d'entrées dupliquées. J'envisage donc d'utiliser un Set
au lieu d'un LinkedList
, mais les critères pour décider si deux frais sont égaux résident dans la méthode equals
remplacée dans le Fee
classe.
Si vous utilisez un LinkedList
, je devrai parcourir chaque élément de la liste et appeler la méthode surchargée equals
dans la classe Fee
avec les entrées restantes comme paramètre. Le simple fait de lire cela semble trop de traitement et ajoutera à la complexité de calcul.
Puis-je utiliser Set
avec une méthode equals
remplacée? Devrais-je?
Comme l'a dit Jeff Foster:
La méthode Set.equals () est uniquement utilisée pour comparer deux ensembles pour l'égalité.
Vous pouvez utiliser un Set
pour vous débarrasser des entrées en double, mais attention: HashSet
n'utilise pas les méthodes equals()
de ses objets contenant pour déterminer l'égalité.
Un HashSet
contient un HashMap
interne avec des entrées <Integer(HashCode), Object>
et utilise equals () ainsi que la méthode equals du HashCode pour déterminer l'égalité.
Une façon de résoudre le problème consiste à remplacer hashCode()
dans la classe que vous placez dans l'ensemble, afin qu'il représente vos critères equals()
Par exemple:
class Fee {
String name;
public boolean equals(Object o) {
return (o instanceof Fee) && ((Fee)o.getName()).equals(this.getName());
}
public int hashCode() {
return name.hashCode();
}
}
Vous pouvez et devez utiliser un ensemble pour contenir un type d'objet avec une méthode d'égalité remplacée, mais vous devrez peut-être également remplacer hashCode (). Les objets égaux doivent ont des codes de hachage égaux.
Par exemple:
public Fee{
public String fi;
public String fo;
public int hashCode(){
return fi.hashCode() ^ fo.hashCode();
}
public boolean equals(Object obj){
return fi.equals(obj.fi) && fo.equals(obj.fo);
}
}
(Avec des contrôles nuls si nécessaire, bien sûr.)
Les sets utilisent souvent hashCode () pour optimiser les performances et se comporteront mal si votre méthode hashCode est cassée. Par exemple, HashSet utilise un HashMap interne.
Si vous vérifiez le code source de HashMap , vous verrez que cela dépend à la fois des méthodes hashCode () et equals () des éléments pour déterminer l'égalité:
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
Si le hachage n'est pas généré correctement, votre méthode equals peut ne jamais être appelée.
Pour rendre votre jeu plus rapide, vous devez générer des codes de hachage distincts pour les objets qui ne sont pas égaux, dans la mesure du possible.
Set
utilise la méthode equals de l'objet ajouté à l'ensemble. Les états JavaDoc
Une collection qui ne contient aucun élément en double. Plus formellement, les ensembles ne contiennent aucune paire d'éléments e1 et e2 tels que e1.equals (e2) et au plus un élément nul.
La méthode Set.equals()
est uniquement utilisée pour comparer deux ensembles pour l'égalité. Il n'est jamais utilisé dans le cadre de l'ajout/suppression d'éléments de l'ensemble.
Une solution serait d'utiliser un TreeSet avec un comparateur.
De la documentation:
L'instance TreeSet effectue toutes les comparaisons d'éléments en utilisant sa méthode compareTo (ou compare), donc deux éléments qui sont considérés comme égaux par cette méthode sont, du point de vue de l'ensemble, égaux.
Cette approche serait beaucoup plus rapide que l'utilisation d'une LinkedList, mais un peu plus lente qu'un HashSet (ln (n) vs n).
Il convient de noter qu'un effet secondaire de l'utilisation de TreeSet serait que votre ensemble est trié.