2012-04-03 38 views
5

का उपयोग करके केवल एक तत्व मौजूद है या नहीं, हाल ही में मुझे संग्रह में केवल एक तत्व मौजूद होने पर 'विशेष मामला' परिदृश्य करने की आवश्यकता थी। ...size() == 1 के लिए जांच की जा रही है और ...iterator.next() का उपयोग करके पुन: प्राप्त करने लग रहा था बदसूरत तो मैं बना लिया है घर काढ़ा संग्रह कक्षा में दो तरीकों:जांचें कि क्या Guava

public class Collections { 
    public static <T> boolean isSingleValue(Collection<T> values) { 
     return values.size() == 1; 
    } 

    public static <T> T singleValue(Collection<T> values) { 
     Assert.isTrue(isSingleValue(values)); 
     return values.iterator().next(); 
    } 
} 

कुछ दिन पहले मुझे पता चला अमरूद Iterables.getOnlyElement कहा जाता विधि है। इसमें मेरी ज़रूरत है और singleValue को प्रतिस्थापित करता है, लेकिन मुझे isSingleValue के लिए मिलान नहीं मिल रहा है। क्या यह डिजाइन द्वारा है? क्या Iterables.isOnlyElement विधि रखने के लिए सुविधा अनुरोध रखना उचित है?

संपादित करें: के बाद से वहाँ कुछ upvotes मैं अमरूद पर वृद्धि खोलने का निर्णय लिया थे - issue 957। अंतिम संकल्प - 'वोंटफिक्स'। तर्क थॉमस/ज़ैरेक्सिस द्वारा प्रदान किए जाने वाले समान ही हैं।

उत्तर

10

ठीक है, आप values.size() == 1 को एक विधि के साथ बदलकर ज्यादा हासिल नहीं करेंगे, सिवाय इसके कि आप शून्य की जांच कर सकते हैं। हालांकि, ऐसा करने के लिए अपाचे कॉमन्स संग्रह (साथ ही साथ गुवा में, मुझे लगता है) में विधियां हैं।

मैं नहीं बल्कि लिखते हैं if(values.size() == 1) या if(SomeHelper.size(values) == 1)
if(SomeHelper.isSingleValue(values)) से - आशय पहले दो दृष्टिकोण में बहुत स्पष्ट है और जितना कोड तीसरे दृष्टिकोण के साथ के रूप में लिखने के लिए है।

6

बस अन्य उत्तर के अलावा: - क्यों प्रश्न का उत्तर (मैं @daveb जो अपने एक नष्ट कर दिया की तरह कुछ लिखने के लिए जा रहा था अगर वहाँ वास्तव में एक तत्व नहीं है , तो Iterables#getOnlyElement एक IllegalArgumentException या NoSuchElementException फेंक जाएगा) Guava में कोई भी Iterables.isSingleValue(Iterable) नहीं है।

मुझे लगता है कि आप यह गलत कर रहे हैं। हैं:

  • विधि invokation राज्य परिवर्तन नहीं करता है (इटरेटर में next() के विपरीत, यही कारण है कि hasNext() मौजूद है)
  • और आप स्पष्ट रूप से और exlicitly कह सकता लौटे कि मूल्य असाधारण मामला नहीं है (विपरीत nullMap#get(Object) से लौटे - यह शून्य मान हो सकता है या यह मतलब हो सकता है कि कुंजी नक्शा में नहीं मिला था)

विधि जाँच अगर हालत सच है और फिर कुछ आपरेशन (दावे से उस में कर रही है) में की तरह की कोई जरूरत नहीं है! आपका नमूना कोड

आप पूरी तरह यकीन है कि इस जगह iterable 1 के अलावा अन्य आकार नहीं हो सकता है, की तुलना में हालत जाँच अनावश्यक है (अपवाद अन्य मामलों में फेंक दिया जाता है) कर रहे हैं।
आप केवल गैर खाली संग्रह में पहला तत्व मिल चाहते हैं - collection.iterator.next() पूरी तरह से ठीक है (यदि संग्रह खाली है NoSuchElementException फेंक दिया जाता है)।
यदि आप Iterables.getFirst(iterable, default) से संग्रह के आकार के बारे में कुछ भी नहीं जानते हैं तो आपके लिए है।

पीएस यदि आपका Collections#isSingleValue केवल स्थानीय रूप से यहां इस्तेमाल किया (इसलिए निजी हो सकता है) कि वास्तव में मतलब है कि आप Iterables#getOnlyValue कॉल करने से पहले उस चेक की जरूरत नहीं है।

पी.पी.एस.अमरूद के डिजाइन के बारे में आपके प्रश्न का एक और जवाब यहोशू ब्लोच के प्रभावी जावा के आइटम 57 हो सकता है - गुवा में मैंने कुछ अलग-अलग सहायक तरीकों का उल्लेख किया है, जो स्पष्ट रूप से कहते हैं कि प्रत्येक के लिए असाधारण मामला क्या है; एपीआई को यथासंभव छोटा रखने के लिए बूलियन चेक को जोड़ा नहीं गया था।

0

अभी मुझे एक ही समस्या है।

मैं इस कोड के साथ हल करने के लिए यह करना होगा:

public static <T> void hasJustOne(T... values) { 
    hasJustOne(Predicates.notNull(), values); 
} 

public static <T> void hasJustOne(Predicate<T> predicate, T... values) { 
    Collection<T> filtred = Collections2.filter(Arrays.asList(values),predicate); 
    Preconditions.checkArgument(filtred.size() == 1); 
} 
+0

यह स्पष्ट नहीं है, क्या करता है "मैं हल करने के लिए हूँ" क्या मतलब है? क्या आप कह रहे हैं कि यह एक समाधान है, या आप समस्या पर काम कर रहे हैं? –

+0

यह मेरे लिए समाधान है। – Falci

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