Java'da nesneleri karşılaştırırken, türü karşılaştırarak ve durumu tanımlayarak anlamsal bir kontrol yaparsınız. :
- kendisi (aynı örnek)
- kendisi (klon veya yeniden oluşturulmuş kopya)
- farklı türdeki diğer nesneler
- aynı türden diğer nesneler
null
Kurallar:
- Simetri :
a.equals(b) == b.equals(a)
equals()
her zaman verir true
ya false
, ama asla bir NullpointerException
, ClassCastException
ya da başka herhangi throwable
Karşılaştırma:
- Tür kontrolü : her iki örneğin de aynı türde , yani eşitlik için gerçek sınıfları karşılaştırmanız gerekir. Geliştiriciler
instanceof
tür karşılaştırması için kullandıklarında (bu yalnızca alt sınıflar olmadığı sürece çalışır ve simetri kuralını ihlal ettiğinde A extends B -> a instanceof b != b instanceof a)
.
- Durumun anlamsal kontrolü : Örneklerin hangi durumla tanımlandığını anladığınızdan emin olun. Kişiler sosyal güvenlik numaralarına göre tanımlanabilir, ancak saç rengine (boyanabilir), ismine (değiştirilebilir) veya yaşına (her zaman değişir) göre tanımlanamaz. Yalnızca değer nesneleriyle tam durumu (tüm geçici olmayan alanlar) karşılaştırmalısınız, aksi takdirde yalnızca örneği tanımlayan şeyi kontrol edin.
Senin için Person
sınıfta:
public boolean equals(Object obj) {
// same instance
if (obj == this) {
return true;
}
// null
if (obj == null) {
return false;
}
// type
if (!getClass().equals(obj.getClass())) {
return false;
}
// cast and compare state
Person other = (Person) obj;
return Objects.equals(name, other.name) && Objects.equals(age, other.age);
}
Yeniden kullanılabilir, genel hizmet sınıfı:
public final class Equals {
private Equals() {
// private constructor, no instances allowed
}
/**
* Convenience equals implementation, does the object equality, null and type checking, and comparison of the identifying state
*
* @param instance object instance (where the equals() is implemented)
* @param other other instance to compare to
* @param stateAccessors stateAccessors for state to compare, optional
* @param <T> instance type
* @return true when equals, false otherwise
*/
public static <T> boolean as(T instance, Object other, Function<? super T, Object>... stateAccessors) {
if (instance == null) {
return other == null;
}
if (instance == other) {
return true;
}
if (other == null) {
return false;
}
if (!instance.getClass().equals(other.getClass())) {
return false;
}
if (stateAccessors == null) {
return true;
}
return Stream.of(stateAccessors).allMatch(s -> Objects.equals(s.apply(instance), s.apply((T) other)));
}
}
Senin için Person
sınıf, bu yarar sınıfını kullanarak:
public boolean equals(Object obj) {
return Equals.as(this, obj, t -> t.name, t -> t.age);
}