2011-01-04 16 views
5

में कोई मामला असंवेदनशील मल्टीमैप है, मुझे एक बहु मानचित्र की आवश्यकता है जो कुंजी केस असंवेदनशील है। क्या Google संग्रह में ऐसा कार्यान्वयन है?Google संग्रह

+0

Google संग्रह को गाया गया टैग जोड़ दिया गया है, क्योंकि यह Google संग्रह का उत्तराधिकारी है –

उत्तर

9

यहाँ एक ForwardingMap का मामला असंवेदनशील संस्करण है:

public class CaseInsensitiveForwardingMap<V> extends ForwardingMap<String, V> 
    implements Serializable{ 

    private static final long serialVersionUID = -7741335486707072323L; 

    // default constructor 
    public CaseInsensitiveForwardingMap(){ 
     this(new HashMap<String, V>()); 
    } 

    // constructor with a supplied map  
    public CaseInsensitiveForwardingMap(final Map<String, V> inner){ 
     this.inner = inner; 
    } 

    private final Map<String, V> inner; 
    @Override 
    protected Map<String, V> delegate(){ 
     return inner; 
    } 

    // convert keys to lower case Strings, preserve null keys 
    private static String lower(final Object key){ 
     return key == null ? null : key.toString().toLowerCase(); 
    } 

    @Override 
    public V get(final Object key){ return inner.get(lower(key)); } 
    @Override 
    public void putAll(final Map<? extends String, ? extends V> map){ 
     if(map == null || map.isEmpty()){ inner.putAll(map); } 
     else{ 
      for(final Entry<? extends String, ? extends V> entry : 
       map.entrySet()){ 
        inner.put(lower(entry.getKey()), entry.getValue()); 
      } 
     } 
    } 
    @Override 
    public V remove(final Object object){ return inner.remove(lower(object)); } 
    @Override 
    public boolean containsKey(final Object key){ 
     return inner.containsKey(lower(key)); 
    } 
    @Override 
    public V put(final String key, final V value){ 
     return inner.put(lower(key), value); 
    } 
} 

इस नक्शे का उपयोग करके आप MultiMapMultiMaps में प्रदायक तरीकों का उपयोग कर बना सकते हैं।

उदाहरण:

Map<String, Collection<String>> map = 
    new CaseInsensitiveForwardingMap<Collection<String>>(); 
Multimap<String, String> caseInsensitiveMultiMap = 
    Multimaps.newMultimap(map, new Supplier<Collection<String>>(){ 

     @Override 
     public Collection<String> get(){ return Sets.newHashSet(); } 

    }); 

चेतावनी: keySet() केवल छोटे मूल्यों वापस आ जाएगी, चाहे कैसे चाबियाँ नहीं डाला गया।

+3

ध्यान दें कि इसके लिए String.toLowerCase के बजाय String.toUpperCase का उपयोग करना बेहतर है, क्योंकि कुछ वर्णों को ऊपरी चरण के दौरान कई वर्णों में मैप किया जाता है, लेकिन कम समय के दौरान नहीं। उदाहरण के लिए, वर्ण '\ u00df' को अपरकेस '\ u0053 \ u0053' में मैप किया गया है, जबकि' \ u0053 \ u0053' को लोअरकेस '\ u0073 \ u0073' में मैप किया गया है। लेकिन स्पष्ट रूप से '\ u00df' को' \ u0073 \ u0073' जैसा नहीं माना जाता है जबकि यह अर्थात् है। –

+0

@ फ्रोर वाह, उसे नहीं पता था! धन्यवाद! –

1

नहीं, लेकिन संभवतः आप स्ट्रिंग कुंजी का उपयोग कर रहे हैं? यदि हां, तो नियमित मल्टीमैप तक पहुंच को सामान्य क्यों न करें? 80% मामले के लिए, यह सभी कॉल रखेगा और कुंजी को कम करता है।

केस-संवेदी multimaps साथ मुद्दों की एक पूरी चर्चा के लिए, देखें this google group discussion

5

आप एक Map<String,List<Payload>> का उपयोग नहीं किया जा सका है और यह एक Comparator<String> जो किया था एक केस-संवेदी तुलना दे सकता है?

ऐसा प्रतीत होता है कि न तो Google संग्रह और न ही अपाचे संग्रह ढांचे में एक बहुआयामी है जो महत्वपूर्ण समानता का मूल्यांकन करने के लिए एक तुलनाकर्ता को स्वीकार करता है।

+3

[MultiMaps.newListMultiMap()] का उपयोग करें (http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/ google/common/collect/Multimaps.html # newListMultimap% 28java.util.Map% 2C% 20com.google.common.base.Supplier% 29) और एक कस्टम तुलनित्र –

+0

के साथ 'ट्रीमैप' की आपूर्ति करें मानक जावा बराबर इग्निरेसेज़ कॉल को आंतरिक रूप से लॉवरकेज़ – sds

2

आप Collator का उपयोग कर केस-असंवेदनशील स्ट्रिंग तुलनाकर्ता को परिभाषित कर सकते हैं। फिर उस तुलनाकर्ता द्वारा क्रमबद्ध कुंजी के साथ एक TreeMultimap बनाएँ।