2011-09-30 3 views
9

में हैश मैप से वाइल्डकार्ड मैचों की एक सूची लौटने पर मेरे पास हैशमैप है जिसमें स्ट्रिंग में वाइल्डकार्ड (*) हो सकता है।जावा

उदाहरण के लिए,

HashMap<String, Student> students_; 

एक प्रमुख के रूप में जॉन * हो सकता है। मैं जानना चाहता हूं कि क्या जॉनस्मिथ छात्रों_ में किसी भी तत्व से मेल खाता है। मेरी स्ट्रिंग के लिए कई मैचों (जॉन *, जो * स्मिथ, आदि) हो सकते हैं। क्या मेरे पास हैश मैप से इन मैचों की सूची प्राप्त करने का कोई तरीका है?

क्या कोई अन्य वस्तु है जिसका उपयोग मैं कर सकता हूं जिसके लिए मुझे अपने संग्रह में हर तत्व के माध्यम से पुनरावृत्ति करने की आवश्यकता नहीं है, या क्या मुझे इसे चूसना है और सूची वस्तु का उपयोग करना है?

एफवाईआई, मेरे संग्रह में 200 से कम तत्व होंगे, और आखिरकार मैं जोड़ी जो कम से कम वाइल्डकार्ड से मेल खाती है उसे ढूंढना चाहूंगा।

+2

हैशिंग कार्यों एक तरह से निर्माण कर रहे हैं कि मामूली परिवर्तन (जैसे: 'जॉन SmitH' को' जॉन स्मिथ ') पूरी तरह से अलग हैश पैदा करते हैं। – NullUserException

+0

आप फिर से क्यों नहीं करना चाहते हैं? यह बुरा नहीं है (विशेष रूप से 200 से कम तत्वों के साथ), और आखिरकार किसी भी अन्य समाधान में प्रदर्शन के मामले में कुछ समान शामिल होगा। – Guillaume

+0

200 से कम तत्वों पर, केवल 'एंट्रीसेट() 'पर रैखिक खोज करें और प्रत्येक कुंजी के विरुद्ध अपने वाइल्डकार्ड का मूल्यांकन करें।यदि यह बहुत अधिक होता, तो मैंने एक (एम्बेडेड) डेटाबेस और 'LIKE' क्वेरी का सुझाव दिया था। –

उत्तर

1

हैशिंग फ़ंक्शन की वजह से हैसम के साथ हासिल करना संभव नहीं है। इसे "John*" का हैश और "John Smith" एट अल का हैश असाइन करना होगा। वही मूल्य

आप एक ट्री-मैप के साथ यह कर सकता है, यदि आप अपने स्वयं के कस्टम वर्ग WildcardString रैपिंग स्ट्रिंग लिखते हैं, और इस तरह से कि "John*".compareTo("John Smith") रिटर्न 0. आप रेगुलर एक्सप्रेशन के साथ ऐसा कर सकता है की तरह other answers पहले ही बताया है में compareTo लागू।

यह देखते हुए कि आप विस्तृत कार्डकार्ड मिलान की सूची चाहते हैं, तो आप हमेशा उन्हें प्रविष्टियों को हटा सकते हैं, और TreeMap.get() को पुन: सक्रिय कर सकते हैं। नाम के साथ समाप्त होने के बाद चाबियाँ वापस रखना याद रखें।

यह हासिल करने का यह एक संभव तरीका है। 200 से कम तत्वों के साथ आप ठीक पुनरावृत्त होंगे।

अद्यतन:TreeSet पर सही ढंग से लागू करने के क्रम में, आप दो WildcardString रों की तुलना के मामले को अलग कर सकता है (अर्थात यह कुंजी के बीच एक comparation है) और (एक खोज मूल्य के साथ एक चाबी की तुलना) एक String करने के लिए एक WildcardString की तुलना ।

+0

धन्यवाद, ज़वी। 200 की एक सूची के लिए आपको लगता है कि ट्रीसेट का उपयोग करने के लिए कोई प्रदर्शन लाभ होगा? – Sarah

+2

वाइल्डकार्डस्ट्रिंग क्लास में तुलना करने के लिए (स्ट्रिंग) विधि की तुलना करना तुलना के अनुबंध को तोड़ देगा क्योंकि विधि: 'wildCardString.compareTo (string)' विपरीत चिह्न या 'string.compareTo (wildCardString) 'नहीं हो सकता है। इसके अतिरिक्त यह अनुशंसा की जाती है कि तुलना बराबर के अनुरूप है। – Jim

+0

@jim आपकी अंतर्दृष्टि, अच्छी बात के लिए धन्यवाद। –

3

आप मिलान करने के लिए रेगेक्स का उपयोग कर सकते हैं, लेकिन आपको पहले "John*" को रेगेक्स समतुल्य "John.*" में बदलना होगा, हालांकि आप उस उड़ान पर कर सकते हैं।

String name = "John Smith"; // For example 
Map<String, Student> students_ = new HashMap<String, Sandbox.Student>(); 

for (Map.Entry<String, Student> entry : students_.entrySet()) { 
    // If the entry key is "John*", this code will match if name = "John Smith" 
    if (name.matches("^.*" + entry.getKey().replace("*", ".*") + ".*$")) { 
     // do something with the matching map entry 
     System.out.println("Student " + entry.getValue() + " matched " + entry.getKey()); 
    } 
} 
+1

उन्होंने विशेष रूप से कहा कि वह सभी प्रविष्टियों पर पुन: प्रयास नहीं करना चाहते थे ... – Guillaume

+0

@ गुइलाइम नहीं, उन्होंने विशेष रूप से ** नहीं ** कहा। विशेष रूप से, उन्होंने कहा: * क्या कोई और वस्तु है जिसका उपयोग मैं कर सकता हूं जिसके लिए मुझे अपने संग्रह में हर तत्व के माध्यम से पुन: प्रयास करने की आवश्यकता नहीं है, ** या मुझे इसे चूसना है और एक सूची वस्तु **? * का उपयोग करना है। मैंने * OR * भाग की पुष्टि करके प्रश्न का उत्तर दिया। – Bohemian

+1

बोहेमियन, आप सोफिस्ट :-) मैं वैसे भी आपके उत्तर से सहमत हूं। मैं नहीं देखता कि वह फिर से क्यों नहीं हटना चाहता। – Guillaume

0

तुम बस यह एक सूची में परिवर्तित करने के बिना अपने मानचित्र पुनरावृति कर सकते हैं और स्ट्रिंग, समारोह से मेल खाता है wih एक regexp का उपयोग करता है का उपयोग करें:

यहाँ कुछ कोड है कि काम करता रहेगा।

आप पाश से बचना चाहते हैं, तो आप की तरह उपयोग कर सकते हैं अमरूद इस

@Test 
public void hashsetContainsWithWildcards() throws Exception { 
Set<String> students = new HashSet<String>(); 
students.add("John*"); 
students.add("Jo*Smith"); 
students.add("Bill"); 

Set<String> filteredStudents = Sets.filter(students, new Predicate<String>() { 
    public boolean apply(String string) { 
    return "JohnSmith".matches(string.replace("*", ".*")); 
    } 
}); 

assertEquals(2, filteredStudents.size()); 
assertTrue(filteredStudents.contains("John*")); 
assertTrue(filteredStudents.contains("Jo*Smith")); 

} सामान्य रूप में