java - Objects.hash() या अपने हैशकोड() कार्यान्वयन का उपयोग करें?




(2)

ध्यान दें कि Object... का पैरामीटर Object... इसके दो मुख्य परिणाम हैं:

  • हैश कोड गणना में उपयोग किए जाने वाले आदिम मानों को बॉक्स किया जाना चाहिए, उदाहरण के लिए this.id long से long परिवर्तित हो जाती है।
  • विधि का आह्वान करने के लिए एक Object[] बनाना होगा।

यदि hashCode को अक्सर बुलाया जाता है तो इन "अनावश्यक" वस्तुओं को बनाने की लागत बढ़ सकती है।

मैंने हाल ही में Objects.hash() विधि की खोज की है।

मेरा पहला विचार था, कि यह आपके hashCode() कार्यान्वयन को बहुत hashCode() । निम्नलिखित उदाहरण देखें:

@Override
//traditional
public int hashCode() {
    int hash = 5;
    hash = 67 * hash + (int)(this.id ^ (this.id >>> 32));
    hash = 67 * hash + (int)(this.timestamp ^ (this.timestamp >>> 32));
    hash = 67 * hash + Objects.hashCode(this.severity);
    hash = 67 * hash + Objects.hashCode(this.thread);
    hash = 67 * hash + Objects.hashCode(this.classPath);
    hash = 67 * hash + Objects.hashCode(this.message);
    return hash;
}

@Override
//lazy
public int hashCode() {
    return Objects.hash(id, timestamp, severity, thread, classPath, message);
}

हालांकि मुझे कहना है कि यह सच होने के लिए बहुत अच्छा लगता है। इसके अलावा मैंने कभी भी यह उपयोग नहीं देखा है।

क्या आपके अपने हैश कोड को लागू करने की तुलना में Objects.hash() का उपयोग करने के कोई डाउनसाइड्स हैं? मैं उन सभी दृष्टिकोणों का चयन कब करूंगा?

अद्यतन करें

यद्यपि इस विषय को हल के रूप में चिह्नित किया गया है, फिर भी ऐसे उत्तर पोस्ट करना जारी रखें जो नई जानकारी और चिंताओं को प्रदान करते हैं।


मैं दोनों के लिए एक मजबूत तर्क कोशिश करना और बनाना चाहता हूं।

खुलासा खोलना

इस उत्तर के लिए, Objects.hash() , Objects.hashCode() , और इस भूमिका को करने वाली किसी भी लाइब्रेरी द्वारा प्रदान किया गया कोई भी फ़ंक्शन Objects.hashCode() है। सबसे पहले, मैं तर्क देना चाहता हूं, ऑब्जेक्ट्स. Objects.hash() उपयोग करें या स्थिर ऑब्जेक्ट फ़ंक्शंस का उपयोग न करें। इस विधि के लिए या उसके खिलाफ किसी भी तर्क के लिए संकलित कोड के बारे में धारणाएं करने की आवश्यकता होती है जो सत्य होने की गारंटी नहीं है। (उदाहरण के लिए, कंपाइलर ऑप्टिमाइज़र फ़ंक्शन कॉल को इनलाइन कॉल में परिवर्तित कर सकता है, इस प्रकार अतिरिक्त कॉल स्टैक और ऑब्जेक्ट आवंटन को छोड़कर। जैसे लूप जो कुछ भी उपयोगी नहीं करते हैं, इसे संकलित संस्करण में नहीं बनाते हैं (जब तक आप बंद नहीं करते ऑप्टिमाइज़र)। आपको यह भी गारंटी नहीं है कि भविष्य के जावा संस्करणों में JVM संस्करण शामिल नहीं होगा जैसे सी # इस विधि के संस्करण में करता है। (सुरक्षा कारणों से मुझे विश्वास है)) तो इस फ़ंक्शन का उपयोग करने के संबंध में आप केवल एकमात्र सुरक्षित तर्क बना सकते हैं, यह है कि अपने स्वयं के बेवकूफ संस्करण को लागू करने की कोशिश करने के बजाय इस फ़ंक्शन में उचित हैश का ब्योरा छोड़ना आम तौर पर सुरक्षित है।

ऑब्जेक्ट्स के लिए

  • एक अच्छा हैश होने की गारंटी है।
  • लागू करने के लिए 5 सेकंड लेता है।
  • आपके पास इसमें एक बग होगा (किसी भी तरह विशेष रूप से यदि आप कार्यान्वयन को कॉपी-पेस्ट करते हैं)

ऑब्जेक्ट्स के खिलाफ

  • जावा docs हैश क्रॉस-संगतता के बारे में कोई वादा नहीं करता है (क्या एक जेवीएम वी 6 और जेवीएम वी 8 वही मान देंगे? हमेशा ओएस में?)
  • hashCodes बारे में बात, अगर वे "समान रूप से वितरित" होते हैं तो वे सबसे अच्छे काम करते हैं। इसलिए यदि एक int मान केवल सीमा 1 से 100 के लिए मान्य है, तो आप अपने हैश-कोड को "पुनर्वितरित" करना चाहते हैं ताकि सभी एक ही बाल्टी का हिस्सा न हों।
  • यदि आपके पास कोई आवश्यकता है जो आपको सवाल करती है कि ऑब्जेक्ट्सशैश कैसे काम करता है, विश्वसनीयता / प्रदर्शन के अनुसार, सावधानी से सोचें कि हैश कोड वास्तव में आप क्या चाहते हैं, और एक कस्टम हैश-कोडिंग विधि लागू करें जो आपकी आवश्यकताओं को संबोधित करे।




hash