2012-02-24 10 views
5

हर बार जब आप जावा मुख्य चलाते हैं तो अलग हैशकोड मान क्यों होते हैं? नीचे उदाहरण कोड देखें।विभिन्न एनम हैशकोड पीढ़ी?

interface testInt{ 

    public int getValue(); 
} 

enum test implements testInt{ 
    A(1), 
    B(2); 

    private int value; 

    private test(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return this.value; 
    } 
} 

हर बार जब आप चलाने के लिए,

public static void main(String[] args) { 
    System.out.println(test.A.hashCode()); 
} 

वहाँ कंसोल पर विभिन्न मुद्रित मान होंगे। क्यों असंगतता?

उत्तर

3

यदि आप हर बार एक ही मूल्य चाहते हैं, तो .ordinal() या इससे भी बेहतर का उपयोग करें, getValue() का उपयोग करें। आप डिफ़ॉल्ट से हैशकोड() को ओवरराइड कर सकते हैं जो इसे एक संख्या देने के लिए है जो वस्तु के निर्माण के तरीके पर आधारित है।

+0

हां, अब मैं उपयोग कर रहा हूं Value एक समाधान के रूप में। एक इंटरफेस को कार्यान्वित करते समय अलग हैशकोड क्यों देखने के लिए बस पोस्ट बनाया। धन्यवाद। –

2

जावाडॉक्स स्पष्ट रूप से बताता है कि। ग वर्ग

जितना यथोचित व्यावहारिक है वस्तु में हैश कोड विधि के लिए javadocs से, hashCode विधि वर्ग वस्तु द्वारा परिभाषित अलग वस्तुओं के लिए अलग पूर्णांकों वापसी करता है। (यह आमतौर पर एक पूर्णांक में वस्तु की आंतरिक पता परिवर्तित करके कार्यान्वित किया जाता है, लेकिन इस कार्यान्वयन तकनीक JavaTM प्रोग्रामिंग भाषा के लिए आवश्यक नहीं है।)

अपने डेमो कोड के विभिन्न रन के पार

तो, आंतरिक पता कर सकते हैं अलग-अलग मूल्यों को देखने के लिए अलग-अलग है और इसलिए यह सामान्य है।

आपकी ज़रूरतों के आधार पर, यदि आप हैशकोड() विधि को जेवीएम इनवोकेशन में समान मान वापस करने के लिए चाहते हैं, तो आपको कस्टम मान वापस करने के लिए विधि को ओवरराइड करना चाहिए। हालांकि, आपको पता होना चाहिए कि अगर यह हैश आधारित संग्रह (हैश टकराव की संभावना में वृद्धि) में वस्तु का उपयोग किया जाता है तो यह विनाशकारी हो सकता है।

+0

जैसा कि मैंने कहा था। मुझे यहां क्या लाया गया था, मेरे ओरेकल जेवीएम 7 में, साधारण enums का तथ्य था, अलग-अलग रनों पर एक ही हैशकोड लौट रहा था। लेकिन जब विशेष enum के लिए swapped, हर रन के लिए हैशकोड अलग था। –

3

"ऐसी कोई आवश्यकता नहीं है कि हैश मान विभिन्न जावा कार्यान्वयन के बीच, या एक ही कार्यक्रम के विभिन्न निष्पादन रनों के बीच भी हो।"

http://en.wikipedia.org/wiki/Java_hashCode%28%29

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Object.html#hashCode%28%29

public static void main(String[] args) { 
    System.out.println(test.A.hashCode()); 
    System.out.println(test.A.hashCode()); 
} 

इस कोड को अब एक ही hashCode का उत्पादन करेगा।

+0

ठीक है, लेकिन, यह केवल तब होता है जब आपके पास एक एनम है जो इंटरफ़ेस लागू करता है। –

+0

जरूरी नहीं है। यदि आप प्रोग्राम निष्पादन के बीच एक स्ट्रिंग (या कुछ और) के हैशकोड का उत्पादन करने की तुलना कर रहे हैं, तो तथ्य यह है कि वे एक ही कोड उत्पन्न करते हैं, यह एक संयोग हो सकता है। – jn1kk

+0

मुझे लगता है कि संयोग सही शब्द नहीं है। यह वास्तव में उन एंम्स के लिए एक ही हैशकोड मान देता है जो किसी भी इंटरफ़ेस को लागू नहीं करता है। यही वह है जो मुझे यहां इंगित करता है। –

0

शायद कुछ जेवीएम कार्यान्वयन मूल रूप से Enum.ordinal() लौट रहे हैं (जो hashCode भी महान होगा) - लेकिन यह प्रभावी ढंग से कुछ भी नहीं बदलेगा। hashCode() मूल्य निष्पादन या JVMs में संगत होने की आवश्यकता नहीं है। Object.hashCode() के जावाडॉक्स में एकमात्र आवश्यक अनुबंध का वर्णन किया गया है - और यह Object में कार्यान्वयन है जिसका उपयोग enum में किया जाता है।

भी ध्यान रखें कि एक अंतरफलक को लागू करने hashCode() साथ कोई संबंध नहीं है:

public class TestEnum { 

    public static void main(String[] args) { 
     System.out.println(Silly.B.hashCode()); 
     System.out.println(Silly.C.hashCode()); 
     System.out.println(Silly.D.hashCode()); 
    } 
} 

enum Silly { 
    B, C, D 
} 

इस कार्यक्रम भी हर रन पर विभिन्न hashCode() रों देता है।

+0

ठीक है, Silly.B.hashCode, वही वापस करेगा और अलग-अलग कोड नहीं होगा। यदि इंटरफेस को कार्यान्वित करना हैशकोड के साथ कुछ लेना देना नहीं है, तो ऐसा क्यों होता है? क्या आप देखते हैं कि मैं कहां आ रहा हूं? Silly.B.hashCode अलग-अलग रनों पर बराबर है, लेकिन यदि आप मूर्खतापूर्ण सरल इंटरफ़ेस लागू करते हैं, तो Silly.A –

+0

@ VicorHugo के लिए अलग हैशकोड होंगे: आप किस जेवीएम का उपयोग कर रहे हैं? 1.6.0_26-b03 पर यह कभी-कभी समान और कभी-कभी अलग-अलग मान देता है, लेकिन निश्चित रूप से वे हमेशा समान नहीं होते हैं ... –

+0

JVM, jdk1.7.0_02 (ओरेकल) –

0

Enum.hashCode किसी भी विशिष्ट मान (Object.hashCode के नियमों का पालन करने के अलावा) को वापस करने के लिए परिभाषित नहीं किया गया है, और सामान्य कार्यान्वयन कुछ विशेष नहीं करते हैं।

क्यों? यदि आप HashSet में या केवल HashMap में एक कुंजी के रूप में enums (केवल) का उपयोग कर रहे थे, तो आपको इसके बजाय अनुकूलित EnumSet या EnumMap का उपयोग करना चाहिए। अब विचार करें कि HashSet में अन्य प्रकार के साथ enum का उपयोग किया जाना था या नहीं। शायद आपके पास इंटरफेस को लागू करने के लिए कुछ "मानक विकल्प" हैं, लेकिन अन्य अपने विकल्पों के साथ आ सकते हैं। कुछ भी स्टेटलेस करेगा। एक HashSet में एकाधिक enum प्रकार। यदि Enum ने हैश मान के लिए ordinals का उपयोग किया था, तो आपके पास सामान्य टकराव होंगे। System.identityHashCode का उपयोग करके टकराव को मजबूत तरीके से कम कर देता है।

public interface Option { 
} 
public enum StandardOptions implements Option { 
    A, B, C 
} 
enum CustomOptions { 
    P, Q, R 
} 
enum MoreOptions { 
    X, Y, Z 
} 

    Set<Option> options = new HashSet<>(); 
    options.add(A); 
    options.add(P); 
    options.add(X); 

हम वास्तव में A.hashCode() == P.hashCode() == X.hashCode() नहीं चाहते हैं।