2009-08-06 8 views
9

बदलता है जो मुझे चाहिए वह एक संग्रह है जो एकाधिक कुंजी को एक ऑब्जेक्ट तक पहुंचने की अनुमति देता है।एक मान के लिए एकाधिक कुंजी के साथ एक जावा मानचित्र/तालिका की आवश्यकता है। मान आमतौर पर

मुझे इस ऑब्जेक्ट में लगातार बदलाव लागू करने की आवश्यकता है।

यह 500k + प्रविष्टियों के लिए भी कुशल होना चाहिए।

+0

क्या आपने दुर्घटना से अपने प्रश्न को उलट दिया? क्योंकि आप "... नक्शा एकाधिक मानों तक पहुंचने के लिए एक कुंजी के लिए अनुमति देता है", जो मानचित्र इंटरफ़ेस के बारे में सच नहीं है। यह कुंजी और मूल्य के बीच एक मैपिंग में से एक है (हालांकि, ज़ाहिर है, आपका मूल्य संग्रह हो सकता है) – Falaina

+0

जब आप कहते हैं * "इस ऑब्जेक्ट में लगातार बदलाव" * आपका क्या मतलब है? क्या आपका मतलब है कि वस्तु उत्परिवर्तनीय है और आप इसकी स्थिति बदलते हैं? या क्या आपका मतलब है कि आपको एक मैपिंग को दूसरे के साथ प्रतिस्थापित करने की आवश्यकता है (और प्रत्येक संबंधित कुंजी के लिए प्रतिस्थापित करें)? –

उत्तर

15

java.util.Map<K,V> के किसी भी कार्यान्वयन यह कर देगा - वहाँ कितनी बार एक विशेष मान अलग चाबियाँ के तहत जोड़ा जा सकता है पर है कोई प्रतिबंध:

Map<String,Integer> m = new HashMap<String, Integer>(); 
m.put("Hello", 5); 
m.put("World", 5); 
System.out.println(m); // { Hello->5, World->5 } 

आप एक नक्शा जहां एक ही कुंजी जुड़ा हुआ है चाहते हैं एक से अधिक मान के साथ, यह एक बहु नक्शा कहा जाता है और आप google java collections API से एक या Apache's commons-collections

+3

इस दृष्टिकोण के साथ समस्या यह है कि आप – njzk2

+0

@ njzk2 से संबंधित सभी कुंजी से ऑब्जेक्ट को तेज़ी से हटा नहीं सकते हैं, जो जरूरी नहीं है। "यह 500k + प्रविष्टियों के लिए कुशल होना चाहिए" बहुत अस्पष्ट है। –

3

Uhm से ...

प्राप्त कर सकते हैं 10
Map map = new HashMap(); 
Object someValue = new Object(); 
map.put(new Object(), someValue); 
map.put(new Object(), someValue); 

अब नक्शा में एक ही मूल्य होता है, जो विभिन्न चाबियों के माध्यम से सुलभ होता है। यदि वह नहीं है जिसे आप ढूंढ रहे हैं तो आपको अपना प्रश्न फिर से शुरू करना चाहिए। :)

2

इस आप क्या चाहते हैं कर सकते हैं:

import java.util.*; 
class Value { 
    public String toString() { 
     return x.toString(); 
    } 
    Integer x=0; 
} 
public class Main { 
    public static void main(String[] arguments) { 
     Map m=new HashMap(); 
     final Value v=new Value(); 
     m.put(1,v); 
     m.put(2,v); 
     System.out.println(m.get(1)); 
     System.out.println(m.get(2)); 
     v.x=42; 
     System.out.println(m.get(1)); 
     System.out.println(m.get(2)); 
    } 
+0

पूरी तरह से मेरे पास एक समान प्रश्न का उत्तर दिया। – elToro

3

मैं इन सबसे छुटकारा उनके अनुरोध को अलग ढंग से व्याख्या की। क्या होगा यदि कोई एक ही अंतर्निहित मूल्यों तक पहुंचने के लिए दो पूरी तरह से अलग कुंजीसेट चाहता है। उदाहरण के लिए:

"Hello" ------| 
        |----> firstObject 
     3  ------| 

    "Monkey" ------| 
        |----> secondObject 
     72  ------| 

     14  -----------> thirdObject 

    "Baseball" ------| 
        |----> fourthObject 
     18  ------| 

जाहिर है दो नक्शे, पूर्णांक चाबी के लिए एक और स्ट्रिंग कुंजी के लिए एक, काम करने के लिए, के बाद से एक नक्शे में एक अद्यतन अन्य मानचित्र में दिखाई नहीं देगा नहीं जा रहा है हो सकता है। मान लीजिए कि आपने Map<String,Object> को संशोधित किया है, जो "बंदर" को पांचवें ऑब्जेक्ट पर मैप करने के लिए अपडेट कर रहा है। इस संशोधन का नतीजा उस मानचित्र के भीतर Entry<String,Object> को बदलना है, लेकिन इसका निश्चित रूप से दूसरे मानचित्र पर कोई प्रभाव नहीं पड़ता है। तो, जबकि तुम क्या इरादा था:

"Monkey" ------| 
        |----> fifthObject 
     72  ------| 

क्या आप वास्तव में प्राप्त होता है इस होगा:

"Monkey" -----------> fifthObject 

     72  -----------> secondObject 

क्या मैं इस स्थिति में क्या पक्ष नक्शे द्वारा दो पक्ष है, लेकिन इसके बजाय उन्हें Map<String, Integer> कहने के लिए मैं उन्हें Map<String, Integer[]> बना दूंगा, जहां संबंधित सरणी एक सदस्य सदस्य है। पहली बार जब मैं किसी कुंजी को मान के साथ जोड़ता हूं, यदि कोई सरणी अभी तक मौजूद नहीं है और कुंजी शून्य वापस आती है, तो मैं सरणी बना देता हूं, और किसी अन्य कुंजी को जोड़ता हूं जिसे मैं चाहता हूं (उस कुंजी के मानचित्र में)। इसके बाद, मैं केवल सरणी की सामग्री को संशोधित करता हूं, लेकिन सरणी के संदर्भ में कभी भी संदर्भ नहीं देता, और यह एक आकर्षण काम करता है।

"Monkey" -------> fifthObjectArray ------| 
               |-----> fifthObjectArray[0] 
     72  -------> fifthObjectArray ------| 
+0

और यह दो अलग-अलग वर्गों की आवश्यकता नहीं है जिनमें कुंजीपटल शामिल हों - वे दोनों तार हो सकते हैं, उदाहरण के लिए – fragorl

0

अपना प्रश्न वास्तव में मुझे इस वर्ग ऐसी बात को संभालने के लिए बनाने के बारे में सोच मिला है। मैं वर्तमान में 2 डी गेम इंजन पर काम कर रहा हूं और आपके प्रश्न ने मुझे पूरी तरह से सोचने के लिए बनाया है कि मुझे क्या चाहिए।

जिस तरह से आपने इसे लिखा है, मुझे विश्वास है कि आप क्या चाहते हैं;

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

इस कक्षा का के प्रकार प्राथमिक कुंजी प्रकार है। टी प्रकार हैशसेट वैल्यू टाइप है।

जिस तरह से आप को लागू करने और इस वस्तु का उपयोग करें:

MapValueSet<ObjectType1,ObjectType2> mainmap = new 

MapValueSet<ObjectType1,ObjectType2>() 
HashSet<Integer> tags = new HashSet<Integer>(); 
     public void test(){ 
      ObjectType1 = new ObjectType1(); 
      ObjectType2 = new ObjectType2(); 

      tags.add(mainmap.put(ObjectType1,ObjectType2); 
      mainmap.get(ObjectType1,Integer); 
     } 

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

यदि आप मौजूद हैं, तो आप इस कक्षा के मूल्यों की जांच कर सकते हैं, या किस कुंजी ऑब्जेक्ट को सेट किया गया है।

क्लास MapValueSet यहां है;

import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Map; 

public class MapValueSet<K,T> { 

     Indexer indxK = new Indexer(); 
     Indexer indxT = new Indexer(); 

     Map<K,Integer> kTags = new HashMap<K,Integer>(); 
     Map<T,Integer> tTags = new HashMap<T,Integer>(); 

     Map<Integer,HashSet<Integer>> MapK = new HashMap<Integer,HashSet<Integer>>(); 

     Map<Integer,HashSet<Integer>> MapT = new HashMap<Integer,HashSet<Integer>>(); 

public int put(K k, T t){ 
    int tag = -1; 
    if(!kTags.containsKey(k)){ 
     kTags.put(k, indxK.getNextTag()); 
    } 

    if(!MapK.containsKey(kTags.get(k))){ 
     MapK.put(kTags.get(k), new HashSet<Integer>()); 
    } 

    if(!tTags.containsKey(t)){ 
     tTags.put(t, tag = indxT.getNextTag()); 
    } 

    if(!MapT.containsKey(tTags.get(t))){ 
     MapT.put(tag = tTags.get(t), new HashSet<Integer>()); 
    }  
     MapK.get(kTags.get(k)).add(tTags.get(t)); 
     MapT.get(tag = tTags.get(t)).add(kTags.get(k)); 

    return tag; 
} 

     @SuppressWarnings("unchecked") 
     public T get(K k, int tag){ 
      Object[] tArr = tTags.keySet().toArray(); 
      for(int i = 0; i < tArr.length; i++){ 
       if(tTags.get((T)tArr[i])== tag){ 
        return (T)tArr[i]; 
      } 
      } 
      return null; 
     } 

     public boolean removeAtKey(K k, T t){ 
       int kTag = -1; 
       int tTag = -1; 

       if(kTags.get(k) != null){ 
       kTag = kTags.get(k); 
       } 

       if(tTags.get(t) != null){ 
       tTag = tTags.get(t); 
       } 

       if(kTag == -1 || tTag == -1){ 
         System.out.println("Keys are Blank at: removeAtKey(k,t)"); 
         return false; 
       } 

       boolean removed = false; 

         if(MapK.get(kTag) != null){ 
           removed = MapK.get(kTag).remove(tTag); 
         } 
         if(MapT.get(tTag) != null){ 
           MapT.get(tTag).remove(kTag); 
         } 

         if(!MapK.containsKey(kTag)){ 
           kTags.remove(k); 
           indxK.removeTag(kTag); 
         } 

         if(MapK.containsKey(kTag)){ 
           tTags.remove(t); 
           indxT.removeTag(tTag); 

         } 

       return removed; 
     } 

     public void removeAtValue(T t){ 
       if(!tTags.containsKey(t)){ 
         return; 
       } 
       Object[] keyArr = MapT.get(tTags.get(t)).toArray(); 

       for(int i = 0; i < keyArr.length; i++){ 
         MapK.get(keyArr[i]).remove(tTags.get(t)); 
       } 

         indxT.removeTag(tTags.get(t)); 
         MapT.remove(tTags.get(t)); 
         tTags.remove(t); 
     } 

     public boolean mapContains(T t){ 
       if(tTags.get(t) == null){ 
         return false; 
       } 
       int tTag = tTags.get(t); 

       return MapT.get(tTag) != null && !MapT.get(tTag).isEmpty(); 
     } 

     public boolean containsKey(K k){ 

       if(kTags.get(k) == null){ 
         return false; 
       } 

       return MapK.containsKey(kTags.get(k)); 
     } 

     public boolean keyContains(K k, T t){ 

       if(kTags.get(k) != null && tTags.get(t) != null){ 
         return MapK.get(kTags.get(k)).contains(tTags.get(t)); 
       } 

       return false; 

     } 

     @Override 
     public String toString(){ 

       String s = ""; 

       s = s+ "Key  Map: " + MapK.toString() + "\n"; 
       s = s+ "Value Map: " + MapT.toString() + "\n"; 
       s = s+ "KeyTag Map: " + kTags.toString() + "\n"; 
       s = s+ "ValueTag Map: " + tTags.toString() + "\n"; 
       s = s+ "KeyTag List: " + indxK.activeSet().toString() + "\n"; 
       s = s+ "ValueTag List: " + indxT.activeSet().toString(); 

       return s;    
     } 


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