2010-04-05 11 views
63

मुझे एक ऑब्जेक्ट मिला है जो तुलनात्मक <> का उपयोग करके 'प्राकृतिक सॉर्ट ऑर्डर' को परिभाषित करता है। ये ट्रीसेट्स में संग्रहीत किए जा रहे हैं।ऑब्जेक्ट चेंज वैल्यू के रूप में ट्रीसेट सॉर्ट को बनाए रखने के लिए

ऑब्जेक्ट को हटाने और पुनः जोड़ने के अलावा, सॉर्ट ऑर्डर को परिभाषित करने के लिए उपयोग किए जाने वाले सदस्यों को सॉर्ट करने के लिए एक और तरीका है?

+6

+1 अच्छा प्रश्न – skaffman

+0

क्या यह सिर्फ मस्तिष्क जिज्ञासा है, या आप प्रदर्शन या कोड सादगी में कहते हैं, एक विशिष्ट लाभ की तलाश में हैं? – greim

+2

मैं संग्रह के क्रम क्रम को बनाए रखने के लिए एक सरल noninvasive तरीका की तलाश में था क्योंकि घटनाओं के भीतर वस्तुओं को अद्यतन करते हैं। सदस्यता में बदलाव के संग्रह के अन्य उपभोक्ताओं पर साइड इफेक्ट्स हैं। आईएमओ, एक तत्व का एक रिसॉर्ट ट्रिगर करना एक क्रमबद्ध संग्रह के लिए बुनियादी कार्यक्षमता की तरह लगता है। – Stevko

उत्तर

11

जैसा कि अन्य ने ध्यान दिया है, कोई अंतर्निहित तरीका नहीं है। लेकिन आप हमेशा उपवर्ग सकते हैं कि TreeSet, अपनी पसंद के निर्माता (रों) के साथ, और आवश्यक कार्यक्षमता में जोड़ें:

public class UpdateableTreeSet<T extends Updateable> extends TreeSet<T> { 

    // definition of updateable 
    interface Updateable{ void update(Object value); } 

    // constructors here 
    ... 

    // 'update' method; returns false if removal fails or duplicate after update 
    public boolean update(T e, Object value) { 
     if (remove(e)) { 
      e.update(value); 
      return add(e); 
     } else { 
      return false; 
     } 
    } 
} 

तब से, आप ((UpdateableTreeSet)mySet).update(anElement, aValue) कॉल करने के लिए छँटाई मान को अद्यतन करना होगा और खुद छँटाई । इसके लिए आपको अपनी डेटा ऑब्जेक्ट में अतिरिक्त update() विधि लागू करने की आवश्यकता है।

+4

यह काम भी नहीं करेगा। हटाएं (ई) यदि तत्व का मूल्य पहले ही बदल चुका है तो तत्व नहीं ढूंढ पाएगा। –

+1

मूर्खता से, आप सही हैं। फिक्स करने के लिए संपादन ... – tucuxi

+0

डाउन-मतदाता के लिए - क्यों? – tucuxi

-1

मुझे नहीं लगता कि ऐसा करने के लिए बाहर का एक बॉक्स तरीका है।

आप पर्यवेक्षक पैटर्न का उपयोग कर सकते हैं जो किसी भी तत्व के अंदर कोई मान बदलते समय पेड़ को सूचित करता है, फिर यह इसे हटा देता है और फिर से सम्मिलित करता है।

इस तरह आप हाथ से इसे करने की देखभाल किए बिना सूची को क्रमबद्ध रूप से रख सकते हैं .. बेशक इस दृष्टिकोण को प्रविष्टि के व्यवहार को संशोधित करके TreeSet को विस्तारित करने की आवश्यकता होगी (केवल जोड़ा गया आइटम पर मनाया/सूचित करें यांत्रिकी)

+3

मुझे नहीं लगता कि यह काम करेगा। यदि तत्व का मान सॉर्ट ऑर्डर को प्रभावित करने वाले तरीके से बदलता है, तो यह काफी संभावना है कि आप इसे पेड़ में ढूंढने में असमर्थ * होंगे या इसे हटा दें। –

0

केवल उसी तरह से बनाया गया है जिसे निकालना और पुनः जोड़ना है।

2

यदि आपको वास्तव में Set का उपयोग करने की आवश्यकता है, तो आप भाग्य से बाहर हैं, मुझे लगता है। तो आप Collections.sort() उपयोग कर सकते हैं मांग पर List-तरह फिर से करता है, तो अपनी स्थिति इतनी छूट एक Set के बजाय एक List के साथ काम करने के लिए है, -

मैं हालांकि, एक वाइल्डकार्ड में फेंक करने जा रहा हूँ। यह प्रदर्शन करने वाला होना चाहिए, अगर List ऑर्डर को अधिक नहीं बदला जाना चाहिए।

+1

ऐसा करने का कोई फायदा नहीं है - सेट को तेज़ लुकअप, सम्मिलन और निष्कासन की गारंटी देता है, जबकि सूची को तत्वों का पता लगाने के लिए पहले संग्रह .binarySearch का उपयोग करने की आवश्यकता होगी।हटाने और पुनः सम्मिलन के लिए छड़ी बेहतर है। – tucuxi

+0

मुझे एहसास है कि, यही कारण है कि मैंने कहा "अगर आपकी स्थिति पर्याप्त लचीली है"। प्रदर्शन आवश्यकताओं * * सूची 'को व्यावहारिक होने की अनुमति देने के लिए पर्याप्त ढीला हो सकता है। – skaffman

+1

एक सूची में @tucuxi बाइनरी खोज ओ (लॉग एन) है। ट्रीसेट में लुकअप? ओ भी (लॉग एन)। –

1

यह जानने में मदद करता है कि आपकी वस्तुएं छोटे वेतन वृद्धि या बड़े पैमाने पर बदल रही हैं या नहीं। यदि प्रत्येक परिवर्तन बहुत छोटा होता है, तो आप अपने डेटा को उस सूची में डालने के लिए बहुत अच्छा करेंगे जो आप सॉर्ट करते हैं। ऐसा करने के लिए, आप तत्व

  • के सूचकांक को खोजने के लिए संशोधित तत्व
  • जबकि तत्व अपने दाएं पड़ोसी से अधिक है

    1. binarySearch करने के लिए है, अपने दाएं पड़ोसी के साथ यह स्वैप
    2. या अगर ऐसा नहीं होता है: जबकि तत्व अपने कम पड़ोसी पड़ोसी से कम है, तो इसे अपने झुंड पड़ोसी के साथ स्वैप करें।

    लेकिन आपको यह सुनिश्चित करना होगा कि कोई भी ऐसा करने के लिए "आप" के बिना तत्व को बदल सकता है।

    संपादित करें: भी!

    http://publicobject.com/glazedlists/glazedlists-1.5.0/api/ca/odell/glazedlists/ObservableElementList.html

  • 4

    मैं एक ऐसी ही समस्या थी, इस सूत्र और tucuxi के जवाब (धन्यवाद पाया: चमकता हुआ सूचियाँ सिर्फ इस लिए कुछ समर्थन हासिल है!) जिस पर मैंने अपना खुद का UpdateableTreeSet लागू किया। मेरे संस्करण, इस तरह के एक सेट पर करने के लिए

    • पुनरावृति साधन प्रदान करता है
    • अनुसूची (आस्थगित) तत्व अद्यतन/पाश
    • भीतर से हटाने सेट की अस्थायी प्रतिलिपि बनाए बिना और अंत में
    • लूप समाप्त होने के बाद थोक ऑपरेशन के रूप में सभी अपडेट/निष्कासन करें।

    UpdateableTreeSet उपयोगकर्ता से बहुत जटिलता छुपाता है। स्थगित थोक अद्यतन/निष्कासन के अलावा, तुकुक्सी द्वारा दिखाए गए एकल तत्व अद्यतन/निष्कासन अभी भी कक्षा में उपलब्ध है।

    अपडेट 2012-08-07: कक्षा GitHub repository में उपलब्ध है जिसमें योजनाबद्ध नमूना कोड के साथ एक प्रारंभिक रीडमेम के साथ-साथ यूनिट परीक्षण भी दिखाए जाते हैं कि यह कैसे अधिक नहीं है (नहीं)।

    +0

    मुझे यह विचार पसंद है - यह केवल अद्यतन करने योग्य ट्रीसेट के अंदर "स्थगित-अद्यतन" सरणी डालने का संकेत देगा, और उसके बाद सभी अद्यतनों को हटाने के लिए "डू-डिफर्ड-अपडेट" को कॉल करना होगा, और फिर उन्हें दोबारा डालें। – tucuxi

    +0

    जैसा कि मेरे कोड उदाहरण का तात्पर्य है, मैंने यही किया है। यह सिर्फ एक विचार नहीं है, यह एक वास्तविक कार्यान्वयन है। क्या आपने स्रोत कोड के लिंक का पालन किया है और परियोजना में अन्य फाइलों की जांच भी की है ताकि यह देखने के लिए कि अधिक जटिल मामलों में कक्षा का उपयोग कैसे किया जाता है? – kriegaex

    +0

    कोई ज़रूरत नहीं - विचार पर्याप्त स्पष्ट है, और यद्यपि आपकी व्याख्या कुछ हद तक लंबी है, लेकिन मैंने इसे उपयोगी के रूप में वोट दिया। – tucuxi

    1

    मैंने इस समस्या को देखा जब मैं सेब आईफोन व्हील स्क्रॉल के समान एक गतिशील स्क्रॉल फलक को लागू करने का प्रयास कर रहा था। TreeSet में आइटम इस वर्ग के हैं:

    /** 
    * Data object that contains a {@code DoubleExpression} bound to an item's 
    * relative distance away from the current {@link ScrollPane#vvalueProperty()} or 
    * {@link ScrollPane#hvalueProperty()}. Also contains the item index of the 
    * scrollable content. 
    */ 
    private static final class ItemOffset implements Comparable<ItemOffset> { 
    
        /** 
        * Used for floor or ceiling searches into a navigable set. Used to find the 
        * nearest {@code ItemOffset} to the current vValue or hValue of the scroll 
        * pane using {@link NavigableSet#ceiling(Object)} or 
        * {@link NavigableSet#floor(Object)}. 
        */ 
        private static final ItemOffset ZERO = new ItemOffset(new SimpleDoubleProperty(0), -1); 
    
        /** 
        * The current offset of this item from the scroll vValue or hValue. This 
        * offset is transformed into a real pixel length of the item distance from 
        * the current scroll position. 
        */ 
        private final DoubleExpression scrollOffset; 
    
        /** The item index in the list of scrollable content. */ 
        private final int index; 
    
        ItemOffset(DoubleExpression offset, int index) { 
         this.scrollOffset = offset; 
         this.index = index; 
        } 
    
        /** {@inheritDoc} */ 
        @Override 
        public int compareTo(ItemOffset other) { 
         double d1 = scrollOffset.get(); 
         double d2 = other.scrollOffset.get(); 
    
         if (d1 < d2) { 
          return -1; 
         } 
         if (d1 > d2) { 
          return 1; 
         } 
    
         // Double expression has yet to be bound 
         // If we don't compare by index we will 
         // have a lot of values ejected from the 
         // navigable set since they will be equal. 
         return Integer.compare(index, other.index); 
        } 
    
        /** {@inheritDoc} */ 
        @Override 
        public String toString() { 
         return index + "=" + String.format("%#.4f", scrollOffset.get()); 
        } 
    } 
    

    DoubleExpression कुछ समय लग सकता JavaFX मंच की एक runLater कार्य में बंधे होने के लिए, यह क्यों सूचकांक इस आवरण वर्ग में शामिल किया जाता है।

    चूंकि scrollOffset स्क्रॉल व्हील पर उपयोगकर्ता स्क्रॉल स्थिति के आधार पर हमेशा बदल रहा है, हमें अपडेट करने का एक तरीका चाहिए। आमतौर पर ऑर्डर हमेशा समान होता है, क्योंकि ऑफ़सेट आइटम इंडेक्स स्थिति से संबंधित होता है। इंडेक्स कभी भी नहीं बदलता है, लेकिन ऑफसेट वर्तमान vValue से संबंधित सापेक्ष दूरी या ScrollPane की एचवीएलयू संपत्ति के आधार पर नकारात्मक या सकारात्मक हो सकता है।

    को केवल की आवश्यकता होने पर मांग पर अपडेट करने के लिए, बस तुकुक्सी द्वारा उपरोक्त उत्तर के मार्गदर्शन का पालन करें।

    ItemOffset first = verticalOffsets.first(); 
    verticalOffsets.remove(first); 
    verticalOffsets.add(first); 
    

    जहां verticalOffsets एक TreeSet<ItemOffset> है। यदि आप इस अद्यतन स्निपेट को हर बार सेट करते समय सेट से प्रिंट करते हैं, तो आप देखेंगे कि यह अपडेट किया गया है।

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