के साथ एक वर्ग के लिए "सहिष्णु" `बराबर 'और' हैशकोड 'लागू करें मेरे पास float
फ़ील्ड वाला एक वर्ग है। उदाहरण के लिए:फ्लोटिंग पॉइंट सदस्यों
public class MultipleFields {
final int count;
final float floatValue;
public MultipleFields(int count, float floatValue) {
this.count = count;
this.floatValue = floatValue;
}
}
मुझे मूल्य से उदाहरणों की तुलना करने में सक्षम होना चाहिए। अब मैं equals
& hashCode
को सही तरीके से कैसे कार्यान्वित कर सकता हूं?
equals
और hashCode
को लागू करने का सामान्य तरीका सभी क्षेत्रों पर विचार करना है। जैसे ग्रहण निम्नलिखित equals
उत्पन्न करेगा:
public boolean equals(Object obj) {
// irrelevant type checks removed
....
MultipleFields other = (MultipleFields) obj;
if (count != other.count)
return false;
if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
return false;
return true;
}
(और एक समान hashCode
, कि अनिवार्य रूप से count* 31 + Float.floatToIntBits(floatValue)
गणना करता है)।
समस्या यह है कि मेरे एफपी मान गोल करने वाली त्रुटियों के अधीन हैं (वे उपयोगकर्ता इनपुट से, डीबी आदि से आ सकते हैं)। तो मुझे एक "सहिष्णु" तुलना की जरूरत है।
सामान्य समाधान एक ईपीएसलॉन मान का उपयोग करके तुलना करना है (उदा। Comparing IEEE floats and doubles for equality देखें)। हालांकि, मुझे यकीन नहीं है कि मैं इस विधि का उपयोग करके equals
को कैसे कार्यान्वित कर सकता हूं, और अभी भी है जो equals
के साथ है।
long comparisonFloatValue = Math.round(floatValue* (Math.pow(10, RELEVANT_DIGITS)));
फिर
अगर मैं equals
में comparisonFloatValue
साथ floatValue
के सभी उपयोगों की जगह:
मेरा विचार सार्थक अंकों की संख्या की तुलना के लिए, तो हमेशा दौर अंकों की उस नंबर पर दोनों equals
और hashCode
में परिभाषित करने के लिए है और hashCode
, मुझे "सहनशील" तुलना मिलनी चाहिए, जो hashCode
के अनुरूप है।
- क्या यह काम करेगा?
- क्या आपको इस दृष्टिकोण के साथ कोई समस्या है?
- क्या ऐसा करने का कोई बेहतर तरीका है? यह बल्कि जटिल लगता है।
क्या आपने अभी फ़्लोटिंग-पॉइंट ** का उपयोग नहीं किया है और इसके बजाय एक निश्चित-बिंदु प्रतिनिधित्व पर स्विच किया है? –
@ करल: हाँ, अच्छा बिंदु, और हाँ, मैंने किया। समस्या यह है कि डीबी में मूल्य एफपी (जो बदलना मुश्किल है, क्योंकि यह हमारे नियंत्रण में नहीं है), इसलिए मुझे डीबी से पढ़ने के दौरान गोल करना होगा। मैं ऐसा नहीं करना चाहता, क्योंकि मुझे लगता है कि आंतरिक रूप से एफपी का उपयोग करना और आउटपुट पर केवल गोल करना बेहतर है। – sleske
ओह, बस ध्यान दिया कि मैंने^ऑपरेटर का उपयोग किया था। बेशक मेरा मतलब एक्सपोनेंटिएशन था, बाइनरी ऑपरेटर नहीं। 'Math.pow' का उपयोग करने के लिए फिक्स्ड। – sleske