मैं एक परियोजना जहां कई वर्गों equals
और hashCode
के समुचित ठेठ कार्यान्वयन की जरूरत पर काम कर रहा हूँ की पुन: प्रयोज्य कार्यान्वयन: प्रत्येक वर्ग ("गहरा" अपरिवर्तनीय वस्तुओं के साथ निर्माण पर प्रारंभ अंतिम क्षेत्रों का एक सेट null
रों करना है है कुछ मामलों में स्वीकार किया जाना है) हैशिंग और तुलना के लिए इस्तेमाल किया जाना चाहिए।बराबरी और hashCode
बॉयलरप्लेट कोड की मात्रा को कम करने के लिए, मैंने इस तरह के व्यवहार के सामान्य कार्यान्वयन प्रदान करने वाले एक अमूर्त वर्ग को लिखने के बारे में सोचा।
public abstract class AbstractHashable {
/** List of fields used for comparison. */
private final Object[] fields;
/** Precomputed hash. */
private final int hash;
/**
* Constructor to be invoked by subclasses.
* @param fields list of fields used for comparison between objects of this
* class, they must be in constant number for each class
*/
protected AbstractHashable(Object... fields) {
this.fields = fields;
hash = 31 * getClass().hashCode() + Objects.hash(fields);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || !getClass().equals(obj.getClass())) {
return false;
}
AbstractHashable other = (AbstractHashable) obj;
if (fields.length != other.fields.length) {
throw new UnsupportedOperationException(
"objects of same class must have the same number of fields");
}
for (int i=0; i<fields.length; i++) {
if (!fields[i].equals(other.fields[i])) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
return hash;
}
}
यह इस तरह से इस्तेमाल किया जा करने का इरादा है:
public class SomeObject extends AbstractHashable {
// both Foo and Bar have no mutable state
private final Foo foo;
private final Bar bar;
public SomeObject(Foo foo, Bar bar) {
super(foo, bar);
this.foo = Objects.requireNonNull(foo);
this.bar = bar; // null supported
}
// other methods, no equals or hashCode needed
}
यह मूलतः क्या कुछ मतभेद के साथ here प्रस्तावित है।
यह मुझे वर्बोसिटी को कम करने के लिए एक सीधा लेकिन अच्छा दृष्टिकोण प्रतीत होता है और अभी भी equals
और hashCode
के कुशल कार्यान्वयन हैं। हालांकि, जैसा कि मैंने कभी कुछ ऐसा नहीं देखा है (ऊपर दिए गए उत्तर को छोड़कर), मैं विशेष रूप से पूछना चाहता हूं कि आवेदन करने से पहले इस दृष्टिकोण (या संभवतः कुछ सुधार जो लागू किया जा सकता है) के खिलाफ कुछ बिंदु है या नहीं पूरे परियोजना में यह।
मुझे पहले से ही दो मुद्दे दिखाई देते हैं। 1. दो ऑब्जेक्ट्स को बराबर माना जाएगा यदि * सभी * उनके फ़ील्ड मेल खाते हैं। यह हमेशा आप जो चाहते हैं वह नहीं हो सकता है। 2. एक वर्ग केवल एक अन्य वर्ग का विस्तार कर सकता है। क्या आप वास्तव में अन्य वर्गों को विरासत में लाने से अपने वर्गों को लॉक करना चाहते हैं क्योंकि 'बराबर' और 'हैशकोड' पुन: उपयोग करना अधिक महत्वपूर्ण है? – CKing