2012-04-02 11 views
12

में ऐरेलिस्ट के रूप में ऐरेलिस्ट HashMap की कुंजी के रूप में ArrayList जोड़ना संभव होगा। मैं bigrams की आवृत्ति गिनती रखना चाहता हूँ। बिग्राम कुंजी है और मूल्य इसकी आवृत्ति है।हैशमैप

"हे है" जैसे प्रत्येक बड़े समूह के लिए, मैं इसके लिए ArrayList बना देता हूं और इसे HashMap में डालता हूं। लेकिन मुझे सही आउटपुट नहीं मिल रहा है।

class Bigram{ 
    private String firstItem; 
    private String secondItem; 

    <getters/setters> 

    @Override 
    public int hashCode(){ 
     ... 
    } 

    @Override 
    public boolean equals(){ 
     ... 
    } 
} 

बजाय वस्तुओं की सीमित संख्या (दो) के लिए गतिशील संग्रह का उपयोग करके:

public HashMap<ArrayList<String>, Integer> getBigramMap (String word1,String word2){ 
    HashMap<ArrayList<String>, Integer> hm = new HashMap<ArrayList<String>, Integer>(); 
    ArrayList<String> arrList1 = new ArrayList<String>(); 
    arrList1 = getBigram(word1, word2);  
    if(hm.get(arrList1) !=null){ 
     hm.put(arrList1, hm.get(arrList1)+1); 
    } 
     else { 

      hm.put(arrList1, 1); 
     } 
    System.out.println(hm.get(arrList1)); 
    return hm; 
} 


public ArrayList<String> getBigram(String word1, String word2){ 
    ArrayList<String> arrList2 = new ArrayList<String>(); 
    arrList2.add(word1); 
    arrList2.add(word2); 
    return arrList2; 
} 

उत्तर

2

आप कुछ इस तरह का प्रयोग क्यों नहीं कर सकते।

+1

मैं भी सेटर्स को छोड़ दूंगा और इसे अपरिवर्तनीय बना दूंगा। निर्माण के बाद उस वर्ग की वस्तुओं को बदलने का शायद कोई कारण नहीं है। –

+0

+1 - वास्तव में, यह शायद ** ** स्थान बचाता है, क्योंकि बिग्राम क्लास में 32-बिट 'लंबाई' फ़ील्ड का ओवरहेड नहीं होगा। –

-3

ArrayList.equals()java.lang.Object से विरासत में मिला है - इसलिए equals() ArrayList पर सूची की सामग्री से स्वतंत्र है।

आप एक नक्शा कुंजी के रूप में एक ArrayList का उपयोग करना चाहते हैं, तो आप एक ही equals() के लिए एक कॉल पर एक ही क्रम बदले में सामग्री सच के साथ दो arraylists बनाने के लिए और एक ही hashCode वापस जाने के लिए में equals() और hashcode() ओवरराइड करने के लिए की आवश्यकता होगी hashcode() पर कॉल पर।

क्या कोई विशेष कारण है कि में है जो ऐरेलिस्ट का उपयोग करने के लिए कुंजी के रूप में एक सरल स्ट्रिंग कहने के विपरीत है?

संपादित करें: मुझे अनदेखा करें, जैसा कि जोआचिम सॉर ने नीचे बताया, मैं इतना गलत हूं कि यह भी मजाकिया नहीं है।

+5

असल में 'ArrayList'' सारसूचीसूची ') का उपयोग करता है जो कि ठीक से लागू किया गया है। असल में प्रत्येक सही 'सूची' कार्यान्वयन को 'बराबर() 'और' हैशकोड() 'कार्यान्वयन के अनुरूप होना आवश्यक है। –

+1

आह, सुधार के लिए धन्यवाद। मैंने अभी ArrayList स्रोत का त्वरित स्कैन किया है और आगे बढ़ने के लिए परेशान नहीं किया - महाकाव्य मेरे हिस्से में असफल रहा। – mcfinnigan

+0

संकेत: ग्रहण में एक रूपरेखा संवाद खोलने के लिए Ctrl-O है, 'बराबर' दर्ज करें, कोई परिभाषा नहीं देखें, विरासत सदस्यों को देखने के लिए फिर से Ctrl-O दबाएं और देखें कि वास्तव में 4 विरासत वाले लोग हैं ('ऑब्जेक्ट ',' संग्रह', 'सूची' और' सारसूची ')। मुझे यकीन है कि अन्य आईडीई में भी इसी तरह के शॉर्टकट हैं। –

18

हाँ आप एक हैश मानचित्र में एक कुंजी के रूप में ArrayList रों हो सकता है, लेकिन यह एक बहुत बुरा विचार है क्योंकि वे परिवर्तनशील हैं।

यदि आप ArrayList किसी भी तरह से (या इसके किसी भी तत्व) में बदलते हैं, तो मानचित्रण मूल रूप से खो जाएगा, क्योंकि कुंजी के पास hashCode जैसा नहीं था जब इसे डाला गया था।

अंगूठे का नियम हैश मानचित्र में कुंजी के रूप में केवल अपरिवर्तनीय डेटा प्रकारों का उपयोग करना है। एलेक्स Stybaev द्वारा सुझाव दिया गया है, तो आप शायद इस तरह की एक Bigram वर्ग बनाना चाहते हैं:

final class Bigram { 

    private final String word1, word2; 

    public Bigram(String word1, String word2) { 
     this.word1 = word1; 
     this.word2 = word2; 
    } 

    public String getWord1() { 
     return word1; 
    } 

    public String getWord2() { 
     return word2; 
    } 

    @Override 
    public int hashCode() { 
     return word1.hashCode()^word2.hashCode(); 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return (obj instanceof Bigram) && ((Bigram) obj).word1.equals(word1) 
             && ((Bigram) obj).word2.equals(word2); 
    } 
} 
+0

इसके अलावा यह व्यवहार्य होने के अलावा, शायद 'बिग्राम' कक्षा को पेश करना एक अच्छा विचार है, यदि वह वास्तव में काम कर रहा है। –

1

इस प्रयास करें, यह काम करेंगे।

public Map<List, Integer> getBigramMap (String word1,String word2){ 
    Map<List,Integer> hm = new HashMap<List, Integer>(); 
    List<String> arrList1 = new ArrayList<String>(); 
    arrList1 = getBigram(word1, word2);  
    if(hm.get(arrList1) !=null){ 
     hm.put(arrList1, hm.get(arrList1)+1); 
    } 
    else { 
     hm.put(arrList1, 1); 
    } 

    System.out.println(hm.get(arrList1)); 
    return hm; 
} 
+0

इसके साथ समस्या यह है कि, मैं ** सूची ** को पैरामीटरेट करने में सक्षम नहीं हूं। क्या आप कृपया मुझे इसके बारे में भी विचार दे सकते हैं? या मुझे इसके लिए एक और धागा शुरू करना चाहिए। – thetna

+0

इसका उपयोग करके, आप मानचित्र पर किसी भी प्रकार की सूची पास कर सकते हैं।सूची स्ट्रिंग, पूर्णांक या उपयोगकर्ता परिभाषित वस्तु का हो सकता है। – vikiiii

2

the documentation से:

नोट: अगर परिवर्तनशील वस्तुओं नक्शा कुंजी के रूप में उपयोग किया जाता है बड़ी सावधानी प्रयोग किया जाना चाहिए। किसी ऑब्जेक्ट का मान निर्दिष्ट नहीं है कि किसी ऑब्जेक्ट का मान इस तरह से बदला गया है जो equals तुलना को प्रभावित करता है जबकि ऑब्जेक्ट मानचित्र में एक कुंजी है। इस निषेध का एक विशेष मामला यह है कि किसी मानचित्र के लिए स्वयं को कुंजी के रूप में रखने की अनुमति नहीं है। जबकि यह एक मानचित्र के रूप में स्वयं को एक मूल्य के रूप में रखने के लिए अनुमत है, अत्यधिक सावधानी सलाह दी गई है: equals और hashCode विधियां अब इस तरह के मानचित्र पर अच्छी तरह से परिभाषित नहीं हैं।

जब आप hashCode और equals की खातिर कुंजी के रूप में परिवर्तनशील वस्तुओं उपयोग कर रहे हैं देखभाल करने के लिए है।

नीचे की रेखा यह है कि अपरिवर्तनीय वस्तुओं को चाबियों के रूप में उपयोग करना बेहतर होता है।

0

यह सुनिश्चित करें कि यह संभव है। मुझे लगता है कि आपके put में समस्या है। बिग्राम के लिए कुंजी प्राप्त करने का प्रयास करें, इसे बढ़ाएं, इस बिग्राम के साथ एंट्री हटाएं और अपडेटेड वैल्यू

-1

कृपया यह समझने के लिए मेरे कोड को नीचे देखें कि क्या नक्शा में ऐरेलिस्ट है और कैसे JVM इनपुट के लिए यह करेगा: यहां मैं लिखता हूं हैशकोड और TesthashCodeEquals कक्षा के लिए विधि बराबर है।

package com.msq; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 

class TesthashCodeEquals { 
    private int a; 
    private int b; 

    public TesthashCodeEquals() { 
     // TODO Auto-generated constructor stub 
    } 



    public TesthashCodeEquals(int a, int b) { 
     super(); 
     this.a = a; 
     this.b = b; 
    } 



    public int getA() { 
     return a; 
    } 

    public void setA(int a) { 
     this.a = a; 
    } 

    public int getB() { 
     return b; 
    } 

    public void setB(int b) { 
     this.b = b; 
    } 

    public int hashCode() { 

     return this.a + this.b; 
    } 

    public boolean equals(Object o) { 

     if (o instanceof TesthashCodeEquals && o != null) { 

      TesthashCodeEquals c = (TesthashCodeEquals) o; 

      return ((this.a == c.a) && (this.b == c.b)); 

     } else 
      return false; 
    } 
} 

public class HasCodeEquals { 
    public static void main(String[] args) { 

     Map<List<TesthashCodeEquals>, String> m = new HashMap<>(); 

     List<TesthashCodeEquals> list1=new ArrayList<>(); 
     list1.add(new TesthashCodeEquals(1, 2)); 
     list1.add(new TesthashCodeEquals(3, 4)); 

     List<TesthashCodeEquals> list2=new ArrayList<>(); 
     list2.add(new TesthashCodeEquals(10, 20)); 
     list2.add(new TesthashCodeEquals(30, 40)); 


     List<TesthashCodeEquals> list3=new ArrayList<>(); 
     list3.add(new TesthashCodeEquals(1, 2)); 
     list3.add(new TesthashCodeEquals(3, 4)); 



     m.put(list1, "List1"); 
     m.put(list2, "List2"); 
     m.put(list3, "List3"); 

     for(Map.Entry<List<TesthashCodeEquals>,String> entry:m.entrySet()){ 
      for(TesthashCodeEquals t:entry.getKey()){ 
       System.out.print("value of a: "+t.getA()+", value of b: "+t.getB()+", map value is:"+entry.getValue()); 
       System.out.println(); 
      } 
      System.out.println("######################"); 
     } 

    } 
} 

output: 

value of a: 10, value of b: 20, map value is:List2 
value of a: 30, value of b: 40, map value is:List2 
###################### 
value of a: 1, value of b: 2, map value is:List3 
value of a: 3, value of b: 4, map value is:List3 
###################### 

तो यह सूची में वस्तुओं की संख्या और वस्तु में valriabe के मूल्यों की जाँच करेगा। यदि ऑब्जेक्ट्स की संख्या समान है और इंस्टेंस चर के मान भी समान हैं तो यह डुप्लिकेट कुंजी पर विचार करेगा और कुंजी को ओवरराइड करेगा।

अब अगर मैं सूची 3 पर वस्तु का केवल मान बदलने

list3.add

(नई TesthashCodeEquals (2, 2));

तो यह प्रिंट होगा:

output 
    value of a: 2, value of b: 2, map value is:List3 
    value of a: 3, value of b: 4, map value is:List3 
    ###################### 
    value of a: 10, value of b: 20, map value is:List2 
    value of a: 30, value of b: 40, map value is:List2 
    ###################### 
    value of a: 1, value of b: 2, map value is:List1 
    value of a: 3, value of b: 4, map value is:List1 
###################### 

ताकि यह हमेशा सूची में वस्तुओं की संख्या और वस्तु की उदाहरण चर के मूल्य की जाँच करें।

धन्यवाद

1

मैं इस समाधान के साथ आया हूं। यह स्पष्ट रूप से सभी मामलों में प्रयोग योग्य नहीं है, उदाहरण के लिए हैशकोड int क्षमता, या list.clone() जटिलताओं को चरणबद्ध करने पर (यदि इनपुट सूची बदल जाती है, तो कुंजी इच्छित के समान रहता है, लेकिन जब सूची की वस्तुएं उत्परिवर्तनीय होती हैं, क्लोन सूची में इसके आइटमों का एक ही संदर्भ है, जिसके परिणामस्वरूप कुंजी बदल जाएगी)।

import java.util.ArrayList; 

public class ListKey<T> { 
    private ArrayList<T> list; 

    public ListKey(ArrayList<T> list) { 
     this.list = (ArrayList<T>) list.clone(); 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 

     for (int i = 0; i < this.list.size(); i++) { 
      T item = this.list.get(i); 
      result = prime * result + ((item == null) ? 0 : item.hashCode()); 
     } 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return this.list.equals(obj); 
    } 
} 

--------- 
    public static void main(String[] args) { 

     ArrayList<Float> createFloatList = createFloatList(); 
     ArrayList<Float> createFloatList2 = createFloatList(); 

     Hashtable<ListKey<Float>, String> table = new Hashtable<>(); 
     table.put(new ListKey(createFloatList2), "IT WORKS!"); 
     System.out.println(table.get(createFloatList2)); 
     createFloatList2.add(1f); 
     System.out.println(table.get(createFloatList2)); 
     createFloatList2.remove(3); 
     System.out.println(table.get(createFloatList2)); 
    } 

    public static ArrayList<Float> createFloatList() { 
     ArrayList<Float> floatee = new ArrayList<>(); 
     floatee.add(34.234f); 
     floatee.add(new Float(33)); 
     floatee.add(null); 

     return floatee; 
    } 

Output: 
IT WORKS! 
null 
IT WORKS! 
+0

आप देखते हैं कि मैंने इसका परीक्षण कैसे किया, किसी कारण से मुझे अभी भी समाधान अविश्वसनीय लगता है। क्या यह वैध है? – Javo

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