कॉमन्स / लैंग बिल्डर्स महान हैं और मैं उन्हें वर्षों से ध्यान देने योग्य प्रदर्शन ओवरहेड (बिना और हाइबरनेट के बिना) के लिए उपयोग कर रहा हूं। लेकिन जैसा कि एलन ने लिखा है, अमरूद का तरीका और भी अच्छा है:
यहाँ एक नमूना है बीन:
public class Bean{
private String name;
private int length;
private List<Bean> children;
}
यहां कॉमन्स / लैंग के साथ बराबर () और हैशकोड () लागू किया गया है:
@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;
}
}
और यहाँ जावा 7 या उच्चतर (अमरूद से प्रेरित) के साथ:
@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;
}
}
नोट: इस कोड ने मूल रूप से अमरूद का संदर्भ दिया था, लेकिन जैसा कि टिप्पणियों ने बताया है, यह कार्यक्षमता तब से जेडीके में पेश की गई है, इसलिए अमरूद की अब आवश्यकता नहीं है।
जैसा कि आप देख सकते हैं कि अमरूद / जेडडीके संस्करण छोटा है और शानदार सहायक वस्तुओं से बचा जाता है। बराबरी के मामले में, यह मूल्यांकन को शॉर्ट-सर्कुलेट करने की भी अनुमति देता है यदि पहले वाला Object.equals()
कॉल गलत होता है (निष्पक्ष होना: कॉमन्स / लैंग में ObjectUtils.equals(obj1, obj2)
समान शब्दार्थ के साथ एक विधि है जिसका उपयोग EqualsBuilder
उपरोक्त के बजाय शॉर्ट-सर्कुलेटिंग की अनुमति देने के लिए किया जा सकता है )।
तो: हाँ, मैन्युअल रूप से निर्मित equals()
और hashCode()
तरीकों (या उन भयानक राक्षस जो आपके लिए उत्पन्न होंगे) पर कॉमन्स लैंग बिल्डर्स बहुत बेहतर हैं , लेकिन जावा 7+ / अमरुद संस्करण और भी बेहतर हैं।
और हाइबरनेट के बारे में एक नोट:
अपने बराबर (), हैशकोड () और स्ट्रींग () कार्यान्वयन में आलसी संग्रह का उपयोग करने के बारे में सावधान रहें। यदि आपके पास एक खुला सत्र नहीं है तो यह बुरी तरह से विफल हो जाएगा।
नोट (बराबरी के बारे में):
a) उपरोक्त दोनों संस्करणों में (), आप इनमें से एक या दोनों शॉर्टकट का भी उपयोग करना चाह सकते हैं:
@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) बराबरी () अनुबंध की आपकी व्याख्या के आधार पर, आप भी लाइन बदल सकते हैं
if(obj instanceof Bean){
सेवा
// make sure you run a null check before this
if(obj.getClass() == getClass()){
यदि आप दूसरे संस्करण का उपयोग करते हैं, तो आप शायद super(equals())
अपने equals()
तरीके के अंदर कॉल करना चाहते हैं । इस विषय पर राय अलग है, इस विषय पर चर्चा की गई है:
सुपरक्लास को अमरूद ऑब्जेक्टशकोड () के कार्यान्वयन में शामिल करने का सही तरीका?
(हालांकि इसके बारे में है hashCode()
, वही लागू होता है equals()
)
नोट ( कयाहर से टिप्पणी से प्रेरित )
Objects.hashCode(..)
(जैसा कि अंतर्निहित है Arrays.hashCode(...)
) यदि आप कई आदिम क्षेत्र हैं तो बुरी तरह से प्रदर्शन कर सकते हैं। ऐसे मामलों में, EqualsBuilder
वास्तव में बेहतर समाधान हो सकता है।
reflectionEquals
औरreflectionHashcode
कार्यों से मोह न हो ; प्रदर्शन एक निरपेक्ष हत्यारा है।