सूचियों या इटेरबल्स को गुवा filter(Iterable<?> unfiltered, Class<T> type)
का उपयोग करके आसानी से फ़िल्टर किया जा सकता है। यह कार्रवाई दो कार्य करता है: सूची फ़िल्टर किया जाता है और दिए गए प्रकार टी के अनुक्रम में रखता तब्दीलजेनेरिक प्रकारों की फ़िल्टरिंग सूचियां
अक्सर हालांकि मैं Iterables<Something<?>>
साथ खत्म हो और मैं कुछ विशेष टी के लिए Iterables<Something<T>>
की किसी परिणाम प्राप्त करना चाहते हैं
यह स्पष्ट है, कि अमरूद प्रकार विलोपन की वजह से बॉक्स से बाहर इस समस्या को हल नहीं कर सकते हैं: Something<T>
अपने टी के बारे में किसी भी प्रत्यक्ष जानकारी प्रदान नहीं करता
चलें कहते हैं कि मैं S<? extends Number>
की तरह कुछ है। अगर मैं कुछ विधेय जो मुझसे कहता है कि अगर S<?>
S<Double>
लिए casted किया जा सकता है मैं एक filer के रूप में उपयोग कर सकते हैं परिभाषित करने में सक्षम हूँ:
<T extends Number> Predicate<S<?>> isOfType(Class<N> type) {...}
साथ:
Iterable<S<?>> numbers;
Iterable<S<?>> filtered = Iterable.filter(numbers, isOfType(Double.class));
फ़िल्टर का कार्य करता है, लेकिन यह परिवर्तन कदम याद करता है। अगर मैं अपने विधेय अच्छी तरह से काम करता है लगता है कि मैं भी कास्टिंग के बारे में सोच सकता है:
Iterable<S<Double>> doubles = (Iterable<S<Double>>) filtered;
लेकिन यह कुछ बदसूरत डाली आपरेशन उजागर करता है।
एक विकल्प के रूप में मैं कास्ट करने के लिए Function<S<?>, S<Double>>
प्रदान कर सकता हूं। Class.cast()
पर कॉन्सस्ट्रास्ट में हालांकि इसे ClassCastException
फेंकना नहीं चाहिए, लेकिन तत्व को जाली (या परिवर्तित) नहीं किया जा सकता है, लेकिन बस null
लौटाएं। इस तरह अनुक्रम किसी भी स्पष्ट कलाकारों के बिना परिवर्तित किया जा सकता है:
<T extends Number> Function<S<?>, S<T>> castOrNull(Class<N> type) {...}
Iterable<S<Double>> doubles = Iterable.filter(numbers, castOrNull(Double.class));
लेकिन सूची वास्तव में फिल्टर नहीं किया जाता है: के बजाय यह अभी भी प्रत्येक तत्व जो परिवर्तित या casted नहीं कर सका S<Double>
करने के लिए अशक्त ऑब्जेक्ट सम्मिलित हैं। लेकिन इस तरह एक अतिरिक्त छानने कदम से आसानी से हल हो सकता है:
Iterable<S<Double>> doubles = Iterables.filter(doubles, Predicates.notNull());
दूसरा समाधान ज्यादा मेरे लिए होशियार लगता है। परिभाषित करने के लिए Function
या तो एक कास्ट (जो अनचेक ऑपरेशन छुपाता है) कर सकता है या यदि आवश्यक हो तो यह वास्तव में कुछ नया ऑब्जेक्ट S<T>
बना सकता है।
शेष प्रश्न यह है: क्या एक ही चरण से आवश्यक रूपांतरित करने और फ़िल्टर करने का कोई शानदार तरीका है? मैं बस की तरह कुछ उपयोगिता समारोह को परिभाषित कर सकते हैं:
<I,O> Iterables<O> convert(
Iterables<O> input,
Function<? super I, ? extends O> convert,
Predicate<? super O> filter);
<I,O> Iterables<O> convert(
Iterables<O> input,
Function<? super I, ? extends O> convert);
कहाँ दूसरा समारोह एक Predicates.notNull()
के साथ पहली बार एक की एक छोटी सी में कटौती है,
लेकिन यह पहला कार्य भी है, क्योंकि अनुमान आवश्यक नहीं है Predicates.notNull()
।
कल्पना करें Iterable<Iterable<? extends Number>>
। कनवर्टर फ़ंक्शन Function<Iterable<? extends Number>, Iterable<Double>>
बस एक फ़िल्टर किए गए अनुक्रम को वापस कर सकता है जो शून्य को वापस करने के बजाय खाली हो सकता है। अतिरिक्त फ़िल्टर Iterables.isEmpty()
का उपयोग कर खाली दृश्यों को अंततः छोड़ सकता है।
यह उपयोगी होगा अगर 'Iterable.filter (...) 'विस्तारित कार्यक्षमता के साथ एक पुनरावर्तनीय लौटाता है ताकि आप श्रृंखला फ़िल्टर कर सकें। '/ * एस संग्रह */Iterable
> युगल = Iterable.filter (संख्याओं, castOrNull (Double.class)) फ़िल्टर। (Predicates.notNull()) फ़िल्टर (Predicates.notEmpty());' – aalkuआप क्यों इसे एक ही चरण में करना चाहते हैं? परिवर्तन और फ़िल्टरिंग अलग-अलग ऑपरेशन हैं। – pawstrong