Dans cet article, je décrirai ma compréhension des méthodes Remplacement
Apache Commons fournit deux excellentes classes d'assistance pour appeler des méthodes
hashCode()
et equals()
. Je veux parler de leur implémentation par défaut, ainsi que de la façon de les remplacer correctement. J'écrirai également sur l'implémentation de ces méthodes à l'aide des classes d'assistance du package Apache Common. Contenu de cet article :
- En utilisant
hashCode()
etequals()
. - Remplacez le comportement par défaut.
- Remplacement
hashCode()
etequals()
utilisation d'Apache Commons Lang. - Quelque chose dont il est important de se souvenir.
- Attention particulière lors de l'utilisation d'ORM.
hashCode()
et equals()
ont été définies dans la classe Object
, qui est la classe parent des objets Java. Par conséquent, tous les objets Java héritent de l’implémentation par défaut de ces méthodes.
Utiliser hashCode() et equals()
La méthodehashCode()
est utilisée pour obtenir un nombre entier unique pour un objet donné. Lorsqu'un objet doit être stocké sous forme de structure de données dans une table de hachage (également appelée compartiment), ce numéro est utilisé pour déterminer son emplacement dans cette table. Par défaut, la méthode hashCode()
d'un objet renvoie le numéro de l'emplacement mémoire où l'objet est stocké. La méthode equals()
, comme son nom l'indique, permet de vérifier simplement l'égalité de deux objets. L'implémentation par défaut de cette méthode vérifie simplement les références de deux objets pour voir si elles sont équivalentes.
Remplacement du comportement par défaut
Tout fonctionne bien tant que vous ne remplacez aucune de ces méthodes dans vos cours. Mais parfois, les applications doivent modifier le comportement par défaut de certains objets. Prenons un exemple où vous avez unEmployee
. Écrivons la structure minimale possible d'une telle classe.
public class Employee
{
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
}
La classe décrite ci-dessus Employee
possède quelques attributs de base et méthodes d'accès. Examinons maintenant une situation simple dans laquelle nous devons comparer deux objets de la classe Employee
.
public class EqualsTest {
public static void main(String[] args) {
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.setId(100);
e2.setId(100);
//Печатает false в консоли
System.out.println(e1.equals(e2));
}
}
Il n’est pas nécessaire d’être clairvoyant pour deviner que la méthode ci-dessus renverra « faux ». Mais est-ce réellement exact, étant donné que ces deux objets sont identiques ? Dans une application en temps réel, la méthode doit renvoyer true. Pour obtenir le comportement correct, nous devons remplacer la méthode equals()
, comme suit :
public boolean equals(Object o) {
if(o == null)
{
return false;
}
if (o == this)
{
return true;
}
if (getClass() != o.getClass())
{
return false;
}
Employee e = (Employee) o;
return (this.getId() == e.getId());
}
Ajoutez cette méthode à votre classe Employee
et la vérification d'équivalence renverra « vrai ». Cependant, avons-nous tout fait ? Pas encore. Testons notre classe modifiée d'une autre manière.
import java.util.HashSet;
import java.util.Set;
public class EqualsTest
{
public static void main(String[] args)
{
Employee e1 = new Employee();
Employee e2 = new Employee();
e1.setId(100);
e2.setId(100);
//Печатает 'true'
System.out.println(e1.equals(e2));
Set employees = new HashSet();
employees.add(e1);
employees.add(e2);
//Печатает два an object
System.out.println(employees);
}
}
La commande System.out.println(employee)
imprime deux objets. Si les deux objets étaient équivalents et que Set
seuls des objets uniques étaient contenus, alors HashSet
il ne devrait y avoir qu'une seule instance à l'intérieur, c'est-à-dire les deux objets font référence aux mêmes instances de la classe Employee
. Qu’avons-nous manqué ? Nous avons raté la deuxième méthode importante hashCode()
. Comme le dit la documentation Java, si vous remplacez la méthode equals()
, vous devez alors remplacer la méthode hashCode()
. Alors ajoutons une autre méthode à notre classe Employee
.
@Override
public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + getId();
return result;
}
Nous avons ajouté cette méthode une fois à notre classe, et un seul objet sera imprimé, et ainsi, la vérification de l'équivalence de e1 et e2 s'est avérée vraie.
Remplacement hashCode()
et equals()
utilisation d'Apache Commons Lang
Apache Commons fournit deux excellentes classes d'assistance pour appeler des méthodes hashCode()
et equals()
. Ci-dessous, nous voyons l'utilisation:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
public class Employee
{
private Integer id;
private String firstname;
private String lastName;
private String department;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
@Override
public int hashCode()
{
final int PRIME = 31;
return new HashCodeBuilder(getId()%2==0?getId()+1:getId(), PRIME).
toHashCode();
}
@Override
public boolean equals(Object o) {
if (o == null)
return false;
if (o == this)
return true;
if (o.getClass() != getClass())
return false;
Employee e = (Employee) o;
return new EqualsBuilder().
append(getId(), e.getId()).
isEquals();
}
}
D'un autre côté, si vous utilisez l'un des éditeurs de code, ils devraient également pouvoir appeler de jolies structures pour vous. Par exemple, si dans l'IDE Eclipse vous cliquez avec le bouton droit sur class >> source > Génération de hashCode() et equals()... cela générera une très belle implémentation pour vous. Quelque chose dont il est important de se souvenir.
- Utilisez toujours les mêmes attributs d'objet pour appeler à la fois and
hashCode()
etequals()
. Juste dans notre cas, nous avons utiliséemployee id
. - La méthode
equals()
doit être persistante (si l'objet n'a pas changé, la méthode doit renvoyer la même valeur). - À chaque fois
a.equals(b)
, alorsa.hashCode()
doit être identique àb.hashCode()
. - Si vous remplacez une méthode, vous devez remplacer la seconde.
Attention particulière lors de l'utilisation d'ORM
Si vous utilisez ORM (ru.wikipedia.org/wiki/ORM), utilisez toujours des getters et n'utilisez jamais de références de champhashCode()
. equals()
En effet, dans un ORM, les champs sont de temps en temps chargés à l'aide d'un chargement paresseux et ne sont pas accessibles tant que leurs getters ne sont pas appelés. Par exemple, dans notre classe Employee
, nous utilisons e1.id == e2.id
. Il est tout à fait possible que les i
champs d soient chargés en utilisant un chargement paresseux. L'un des champs peut être 0 ou nul et nous obtiendrons un comportement incorrect. Mais, si , est utilisé e1.getId() == e2.getId()
, nous pouvons en être sûrs même si les champs ont été chargés en utilisant le chargement paresseux ; appeler le getter remplira le champ en premier. C'est tout ce que je sais sur les méthodes hashCode()
and equals()
. J'espère que cela aide quelqu'un quelque part. Bonne chance dans tes études !! ps C'est ma première tentative de traduction. J'ai essayé de tout transmettre le plus près possible de ce que l'auteur voulait dire. Si vous avez des commentaires, veuillez l'écrire dans les commentaires. Ne jugez pas strictement :-))) Article original
GO TO FULL VERSION