Müşterekler / lang inşaatçılar büyük ve ben farkedilir performans yükü (hazırda ve olmadan) olmadan yıllardır kullanıyorum. Ama Alain'in yazdığı gibi, Guava yolu daha da güzel:
İşte bir örnek Bean:
public class Bean{
private String name;
private int length;
private List<Bean> children;
}
Commons / Lang ile uygulanan eşittir () ve hashCode ():
@Override
public int hashCode(){
return new HashCodeBuilder()
.append(name)
.append(length)
.append(children)
.toHashCode();
}
@Override
public boolean equals(final Object obj){
if(obj instanceof Bean){
final Bean other = (Bean) obj;
return new EqualsBuilder()
.append(name, other.name)
.append(length, other.length)
.append(children, other.children)
.isEquals();
} else{
return false;
}
}
ve burada Java 7 veya üstü ile (Guava'dan esinlenilmiştir):
@Override
public int hashCode(){
return Objects.hash(name, length, children);
}
@Override
public boolean equals(final Object obj){
if(obj instanceof Bean){
final Bean other = (Bean) obj;
return Objects.equals(name, other.name)
&& length == other.length // special handling for primitives
&& Objects.equals(children, other.children);
} else{
return false;
}
}
Not: Bu kod başlangıçta Guava'ya atıfta bulundu, ancak yorumların belirttiği gibi, bu işlevsellik o zamandan beri JDK'da tanıtıldı, bu nedenle Guava artık gerekli değildir.
Gördüğünüz gibi Guava / JDK sürümü daha kısadır ve gereksiz yardımcı nesneleri önler. Eşit olması durumunda, daha önceki bir Object.equals()
çağrı yanlış döndürürse değerlendirmenin kısa devre yapılmasına bile izin verir (adil olmak için: commons / lang, yukarıdaki gibi kısa devreye izin vermek ObjectUtils.equals(obj1, obj2)
yerine kullanılabilecek aynı anlamsallığa sahip bir yönteme sahiptir EqualsBuilder
).
Yani: evet, commons lang inşaatçılar manuel olarak inşa edilmiş equals()
ve hashCode()
yöntemlere (veya Eclipse'nin sizin için üreteceği korkunç canavarlara) göre çok tercih edilir , ancak Java 7+ / Guava sürümleri daha da iyidir.
Hazırda Bekletme hakkında bir not:
equals (), hashCode () ve toString () uygulamalarınızda tembel koleksiyonları kullanma konusunda dikkatli olun. Açık bir Oturumunuz yoksa, bu perişan bir şekilde başarısız olacaktır.
Not (yaklaşık olarak eşittir ()):
a) yukarıdaki eşittir () sürümlerinin her ikisinde de bu kısayollardan birini veya her ikisini de kullanmak isteyebilirsiniz:
@Override
public boolean equals(final Object obj){
if(obj == this) return true; // test for reference equality
if(obj == null) return false; // test for null
// continue as above
b) eşittir () sözleşmesini yorumlamanıza bağlı olarak, satır (lar) ı da değiştirebilirsiniz.
if(obj instanceof Bean){
için
// make sure you run a null check before this
if(obj.getClass() == getClass()){
İkinci sürümü kullanıyorsanız, muhtemelen yönteminizin super(equals())
içinde de aramak istersiniz equals()
. Görüşler burada farklı, konu bu soruda tartışılıyor:
Objects.hashcode () uygulamasına süper sınıf eklemenin doğru yolu nedir?
(her ne kadar hakkında olsa da hashCode()
, aynı şey geçerlidir equals()
)
Not ( kayahr'ın yorumundan esinlenmiştir )
Objects.hashCode(..)
(temelde olduğu gibi Arrays.hashCode(...)
) çok sayıda ilkel alanınız varsa kötü performans gösterebilir. Bu gibi durumlarda, EqualsBuilder
aslında daha iyi bir çözüm olabilir.
reflectionEquals
vereflectionHashcode
işlevleri tarafından ayartmayın ; performans mutlak bir katildir.