2010-06-14 11 views
5

के विकल्प के लिए मुझे ऑब्जेक्ट्स का एक क्रमबद्ध सेट चाहिए और वर्तमान में TreeSet का उपयोग कर रहा हूं। मेरी समस्या यह है कि वस्तुओं के compareTo अक्सर 0 लौटाएंगे, जिसका अर्थ है कि उन दो वस्तुओं के क्रम को अपरिवर्तित छोड़ दिया जाना है। TreeMap (डिफ़ॉल्ट रूप से TreeSet द्वारा उपयोग किया जाता है) फिर उन्हें एक ही वस्तु के रूप में माना जाएगा, जो सत्य नहीं है।तुलना करें 0 0 वापस आ सकता है, ट्रीसेट/ट्रीमैप

TreeMap का विकल्प क्या मैं उपयोग कर सकता हूं?


केस का उपयोग करें: मेरे पास प्रदर्शित करने योग्य वस्तुओं का एक सेट है। मैं उन्हें वाई समन्वय द्वारा क्रमबद्ध करना चाहता हूं, ताकि उन्हें सही क्रम में प्रस्तुत किया जा सके। बेशक, दो वस्तुओं में एक ही वाई समन्वय हो सकता है।

+0

दो तत्व एक ही वाई समन्वय, क्या आप ** आप ** पुट है, तो प्रथम? क्या कोई और मानदंड है? – OscarRyz

उत्तर

9

में जोड़े जाने पर ऑब्जेक्ट्स के लिए आप तुलना करने के लिए एक मानदंड परिभाषित कर रहे हैं, लेकिन आपको अतिरिक्त मानदंड जोड़ने की आवश्यकता है।

आप कहते हैं:

मैं प्रदर्शन योग्य वस्तुओं का एक सेट है। मैं उन्हें वाई समन्वय द्वारा क्रमबद्ध करना चाहता हूं, ताकि उन्हें सही क्रम में प्रस्तुत किया जा सके। बेशक, दो वस्तुओं में एक ही वाई समन्वय हो सकता है।

तो, यदि दो तत्वों में एक ही वाई समन्वय है, तो आपने पहले क्या रखा है? अन्य मानदंड क्या होंगे?

यह निर्माण के समय हो सकता है, यह हो सकता है x निर्देशांक, तो आप सिर्फ यह परिभाषित करने के लिए है:

Map<String,Thing> map = new TreeMap<String,Thing>(new Comparator<Thing>(){ 
    public int compare(Thing one, Thing two) { 
     int result = one.y - two.y; 
     if(result == 0) { // same y coordinate use another criteria 
      result = one.x - two.x; 
      if(result == 0) { //still the same? Try another criteria (maybe creation time 
       return one.creationTime - two.creationTime 
      } 
      } 
      return result; 
    } 
}); 

आप को परिभाषित करने के लिए जब एक Thing ऊंची/कम/बराबर है/अन्य Thing से की है। यदि गुणों में से एक दूसरे जैसा ही है, तो शायद आपको उन्हें स्थानांतरित नहीं करना चाहिए। यदि इसका उपयोग करने की तुलना करने के लिए अन्य विशेषता है।

+0

एक अगर कथन! मैंने इसके बारे में क्यों नहीं सोचा और इसके बजाय एक बदसूरत बिट स्थानांतरण हैक लिखा: पी –

+0

लॉल ... कभी-कभी हमारा दिमाग बहुत दूर हो जाता है, और हमें बस * स्पष्ट * दिशा में देखने के लिए बाहर से किसी की आवश्यकता होती है। * मेरी चमक कहाँ है? - एहरम ... आप उन्हें पहन रहे हैं * तरह का :) – OscarRyz

0

मैं अपने ही में से एक विचार है, लेकिन यह

int compare(Object a, Object b) { 
    an = a.seq + (a.sortkey << 16); // allowing for 65k items in the set 
    bn = b.seq + (a.sortKey << 16); 
    return an - bn; // can never remember whether it's supposed to be this or b - a. 
} 
  • sortKey = क्या वास्तव में छंटाई के लिए मायने रखती है, उदाहरण के लिए एक वाई समन्वय
  • seq एक समाधान की अधिक है = एक दृश्य नंबर सौंपा सेट
0

वहाँ 2 महत्वपूर्ण बातें जब क्रमबद्ध सेट (जैसे TreeSet) का उपयोग ध्यान रखना होगा:

1) वे सेट कर रहे हैं; दो बराबर तत्व एक ही संग्रह में अनुमति नहीं है

2) समानता

इसलिए, आपके मामले में आप "तोड़ने संबंधों" चाहिए कुछ माध्यमिक आदेश जोड़कर तुलना तंत्र (या तो तुलनित्र या तुलनीय) के अनुरूप होना चाहिए मानदंड। उदाहरण के लिए: पहले वाई अक्ष का उपयोग करें, फिर एक्स, और उसके बाद कुछ अद्वितीय ऑब्जेक्ट पहचानकर्ता।

भी देखें http://eyalsch.wordpress.com/2009/11/23/comparators/

2

मुद्दा आप में चला रहे हैं कि compareTo लौटने 0 मतलब यह है कि वस्तुओं बराबर हो रहा है।साथ ही, आप उन्हें एक सेट में डाल रहे हैं, जो समान तत्वों की कई प्रतियों की अनुमति नहीं देता है।

या तो अपने compareTo को फिर से लिखें ताकि असमान तत्व अलग-अलग मान वापस कर सकें, या java.util.PriorityQueue जैसे कुछ का उपयोग करें जो बराबर तत्वों की कई प्रतियों की अनुमति देता है।

1

मैंने पहले यह किया है। यह एक आदेश दिया गया बहु-मानचित्र है और यह केवल सूची वस्तुओं का एक वृक्ष है। इस तरह ..

Map<KeyType, List<ValueType>> mmap = new TreeMap<KeyType, List<ValueType>>(); 

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


तो, मैं इस कस्टम एक साथ कंटेनर जल्दी से (पूरी तरह से अपरीक्षित) फेंक दिया, लेकिन यह हो सकता है आप के लिए क्या देख रहे हैं। ध्यान रखें कि आपको केवल इस प्रकार के कंटेनर का उपयोग करना चाहिए यदि आप वास्तव में मूल्य सूचियों के ऑर्डर किए गए मानचित्र की तलाश में हैं। यदि आपके मूल्यों के लिए कुछ प्राकृतिक आदेश है, तो आपको ट्रीसेट का उपयोग करना चाहिए जैसा कि अन्य ने सुझाव दिया है।

public class TestAnything { 

    public static void main(String[] args) { 

     MTreeMap<Integer, String> mmap = new MTreeMap<Integer, String>(); 

     mmap.put(1, "Value1"); 
     mmap.put(2, "Value2"); 
     mmap.put(3, "Value3"); 
     mmap.put(1, "Value4"); 
     mmap.put(3, "Value5"); 
     mmap.put(2, "Value6"); 
     mmap.put(2, "Value7"); 

     System.out.println("size (1) = " + mmap.get(1).size()); 
     System.out.println("size (2) = " + mmap.get(2).size()); 
     System.out.println("size (3) = " + mmap.get(3).size()); 
     System.out.println("Total size = " + mmap.size()); 

     System.out.println(mmap); 
    } 

} 

उत्पादन यह है::

import java.util.LinkedList; 
import java.util.List; 
import java.util.Map; 
import java.util.Set; 
import java.util.TreeMap; 

public class MTreeMap<K, V> { 

    private final Map<K, List<V>> mmap = new TreeMap<K, List<V>>(); 
    private int size = 0; 

    public MTreeMap() { 
    } 

    public void clear() { 
     mmap.clear(); 
     size=0; 
    } 

    public boolean containsKey(K key) { 
     return mmap.containsKey(key); 
    } 

    public List<V> get(K key) { 
     return mmap.get(key); 
    } 

    public boolean isEmpty() { 
     return mmap.isEmpty(); 
    } 

    public Set<K> keySet() { 
     return mmap.keySet(); 
    } 

    public Collection<List<V>> valueLists() { 
     return mmap.values(); 
    } 

    public void put(K key, V value) { 

     List<V> vlist = mmap.get(key); 
     if (null==vlist) { 
     vlist = new LinkedList<V>(); 
     mmap.put(key, vlist); 
     } 
     vlist.add(value); 
     ++size; 
    } 

    public List<V> remove(Object key) { 
     List<V> vlist = mmap.remove(key); 

     if (null!=vlist) { 
     size = size - vlist.size() ; 
     } 
     return vlist; 
    } 

    public int size() { 
     return size; 
    } 

    public String toString() { 
     return mmap.toString(); 
    } 

} 

यहाँ एक अल्पविकसित परीक्षण है

size (1) = 2 
size (2) = 3 
size (3) = 2 
Total size = 7 
{1=[Value1, Value4], 2=[Value2, Value6, Value7], 3=[Value3, Value5]} 
संबंधित मुद्दे