2015-12-01 19 views
6

मुझे एक ऐसा नक्शा बनाना होगा जो किसी तृतीय पक्ष लुकअप सेवा के परिणाम कैश करेगा। अनुरोध दो वस्तुओं से बना है उदाहरण के लिए, time और month। मानचित्र को (time, month) और परिणाम के बीच मानचित्र करने की आवश्यकता है।जावा और जोड़ों के बीच जावा मानचित्र

मेरा प्रारंभिक विचार time और month को प्रभावी ढंग से एक ट्यूपल ऑब्जेक्ट में लपेटने के लिए ऑब्जेक्ट बनाना है, इसलिए कैश इस ऑब्जेक्ट और परिणाम के बीच एक मानचित्र है।

क्या ऐसा करने का कोई बेहतर तरीका है, जब भी हमें कैश का उपयोग करने की आवश्यकता होती है तो टुपल ऑब्जेक्ट में अनुरोध को लपेटने की आवश्यकता होती है?

बहुत धन्यवाद।

+1

समय और महीना .. mmhh, इसे किसी तारीख में संयोजित करने और अपनी नक्शा कुंजी बनाने के बारे में कैसे? –

+1

"क्या ऐसा करने का एक बेहतर तरीका है" आप इस बारे में बुरा होने के लिए क्या समझते हैं? –

+1

क्या आप उस कक्षा के उपयोग (ओं) के साथ उदाहरण दे सकते हैं जो आप करना चाहते हैं और इसके अलावा परिणाम (ओं)? (वास्तव में, मुझे यह समझने की ज़रूरत नहीं है कि आप क्या करना चाहते हैं।) – RyDroid

उत्तर

5

मेरे प्रारंभिक विचार एक वस्तु time और month रैप करने के लिए प्रभावी रूप से एक टपल वस्तु

सही विचार है कि में बनाना है। hashCode() ओवरराइड करने और अपने टपल की equals(Object) यह HashMap<TimeMonthTuple> साथ काम करने के लिए, या compareTo(TimeMonthTuple) यह TreeMap<TimeMonthTuple>

वहाँ ऐसा करने का एक बेहतर तरीका है के साथ काम करने के लिए?

यह सबसे सरल तरीका है, जब तक कि आपके पास ऐसी कक्षा न हो जो TimeMonthTuple को कुछ समझने के साथ प्रतिस्थापित कर सके। उदाहरण के लिए, समय और दिनांक को Date ऑब्जेक्ट में जोड़ा जा सकता है।

कुछ मामलों में आप एक प्राचीन रैपर के आधार पर एक कुंजी बना सकते हैं। उदाहरण के लिए, यदि timemonth 1 और 12 के बीच एक संख्या है मध्यरात्रि के बाद मिनटों की संख्या के रूप में व्यक्त किया जाता है और, समावेशी, आप दोनों मूल्यों एक Integer में लपेट कर सकता है, और एक कुंजी के रूप में उपयोग:

Integer makeTimeMonthKey(int time, int month) { 
    return (time * 12) + (month - 1); 
} 
0

यदि आप एक रैपर ऑब्जेक्ट बनाने से बचना चाहते हैं तो आपको Guava Tables पर एक नज़र डालना चाहिए।

0

आप नक्शे का एक नक्शा बना सकते हैं:

Map<MonthType, Map<TimeType, Value>> map; 

तो आप फोन चाहते हैं:

Value value = map.get(month).get(time); 

एक मूल्य (बशर्ते पुनः प्राप्त करने के आप पहले एक valu जोड़ लिया है month के लिए ई)।

यह विशेष रूप से उपयोग करने के लिए विशेष रूप से अच्छा नहीं है, हालांकि, आपको containsKey/null चेक की बहुत आवश्यकता होगी। इस तरह से भी

class MapOfMaps { 
    final Map<MonthType, Map<TimeType, Value>> map = new HashMap<>(); 

    void put(MonthType month, TimeType time, Value value) { 
    Map<TimeType, Value> timeMap; 
    if (map.containsKey(month)) { 
     timeMap = map.get(month); 
    } else { 
     timeMap = new HashMap<>(); 
     map.put(month, timeMap); 
    } 
    timeMap.put(time, value); 
    } 

    Value get(MonthType month, TimeType time) { 
    if (!map.containsKey(month)) { 
     return null; 
    } 
    return map.get(month).get(time); 
    } 
} 
0

मैं यह कर देंगे, लेकिन जब एक HashMap की एक कुंजी को परिभाषित करने के लिए सावधान रहना:: आप इसे लपेट सकता है एक सुविधा की कक्षा में, अपरिवर्तनीय होना चाहिए अन्यथा बदल रहा है यह मानचित्रण समझौता कर सकता है के बाद से और हैशिंग, और हैश कुंजी की दो आवश्यकताओं को लागू करना चाहिए: हैशकोड और विधियों के बराबर है। कुछ इस तरह:

final class YourWrapper { 
    private final Integer month; 
    private final Integer time; 

    public YourWrapper(Integer month, Integer time) { 
     this.month = month; 
     this.time = time; 
    } 

    public Integer getMonth() { 
     return month; 
    } 

    public Integer getTime() { 
     return time; 
    } 

    @Override 
    public int hashCode() { 
     return month.hashCode()^time.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return (obj instanceof YourWrapper) 
       && ((YourWrapper) obj).month.equals(month) 
       && ((YourWrapper) obj).time.equals(time); 
    } 
} 
0

आप मानचित्र के एक मानचित्र का उपयोग नहीं करना चाहते हैं (बहुत अच्छा नहीं है, लेकिन यह काम करता है) आप अभी भी कुछ विकल्प है ... उदाहरण के लिए एक स्ट्रिंग में महीने के लिए और समय के भंडारण , DateFormat ds = new SimpleDateFormat(MM HH:mm:s) की तरह कुछ का उपयोग कर, तो एक कैलेंडर आपके मूल्यों

Calendar cal = Calendar.getInstance(); 
cal.set(Calendar.MONTH, yourmonth); 
cal.set(Calendar.HOUR_OF_DAY, yourhours); 
cal.set(Calendar.MINUTE, yourminutes); 
cal.set(Calendar.SECOND, yoursecs); 
String val_to_store=ds.format(cal.getTime()); 

या, शायद, आप कैलेंडर वस्तु संग्रहीत कर सकती है के साथ भरा वस्तु कन्वर्ट करने के लिए इस्तेमाल करते हैं।

0

उत्कृष्ट सवाल!

सबसे पहले, @dasblinkenlight का उत्तर सही है, मान लीजिए, ज्यादातर समय। एक ऑब्जेक्ट कुंजी का निर्माण सबसे सीधे आगे और स्पष्ट समाधान है। समझने और काफी कुशलता के लिए यह आसान और स्पष्ट है। यदि यह कैश आपके आवेदन का हॉटस्पॉट नहीं है, तो कोई दूसरा विचार आवश्यक नहीं है।

हालांकि, विकल्प हैं, जो बेहतर दक्षता पैदा कर सकते हैं।

  • यौगिक चाबी के लिए एक एकल कुंजी वस्तु का निर्माण:

    वैचारिक वहाँ दो संभावनाएं हैं। यदि आप डेटाबेस का उपयोग

  • एक दो, या बहु स्तर श्रेणीबद्ध देखने, उदाहरण के लिए यौगिक कुंजी का उपयोग यह एक आम पैटर्न और काफी ठेठ है: store.get(month).get(time)

श्रेणीबद्ध देखने के लिए, कोई अतिरिक्त वस्तु आवंटन की जरूरत है लेकिन, , आप इसे दूसरी हैश टेबल एक्सेस के लिए व्यापार करते हैं। सबसे मेमोरी कुशल होने के लिए, कुंजी को सबसे छोटी मूल्य स्थान के साथ पहले रखना महत्वपूर्ण है।

Cache<Time, Value>[] month2ValueCache = new Cache<Time, Value>[12]; 
{ 
    for (int i = 0; i < 12; i++) { 
    month2ValueCache[i] = new Cache<Time, Value>(...); 
    } 
} 
Value get(int month, Time, time) { 
    return month2ValueCache[month].get(time); 
} 

मैं एक किया:

यह आपके आवेदन की एक बहुत ही केंद्रीय स्थान है, तो और भी बेहतर दृष्टिकोण एक सरणी में, पहले देखने मंच, बारह महीनों रख दिया और स्टार्टअप पर यह प्रारंभ करने में है डेटफ्रैटर के साथ स्वरूपण तिथियों के लिए तुलना बेंचमार्क। यह आपके उपयोग के मामले के समान है। इसमें वास्तव में तीन प्रमुख घटक हैं: दिनांक, प्रारूप और लोकेल। आप इसे यहां पा सकते हैं: https://github.com/headissue/cache2k-benchmark/blob/master/zoo/src/test/java/org/cache2k/benchmark/DateFormattingBenchmark.java

मेरा परिणाम यह था कि वास्तव में यौगिक कुंजी के लिए ऑब्जेक्ट आवंटित करने के बीच बहुत अधिक रनटाइम अंतर नहीं है, या कुंजी के ऑब्जेक्ट आवंटन के बिना तीन स्तर कैश लुकअप नहीं है। हालांकि, प्रयुक्त बेंचमार्क ढांचा कचरे के संग्रह को सही ढंग से ध्यान में रखता नहीं है। मैं एक और बेंचमार्क ढांचे पर स्विच करने के बाद एक और गहन मूल्यांकन करूँगा।

संबंधित मुद्दे