java - जावा 8 जेडीके का उपयोग कर स्ट्रीम करने के लिए Iterable कनवर्ट करें




java-8 java-stream (6)

मेरे पास एक इंटरफ़ेस है जो java.lang.Iterable<T>

मैं जावा 8 स्ट्रीम एपीआई का उपयोग कर उस परिणाम में हेरफेर करना चाहता हूं।

हालांकि Iterable "स्ट्रीम" नहीं कर सकता।

किसी भी बेहतर विचार धाराओं का उपयोग कैसे करें (सूची में Iterable परिवर्तित किए बिना)?


आप आसानी से एक Iterable या Iterator से Stream बना सकते हैं:

public static <T> Stream<T> stream(Iterable<T> iterable) {
    return StreamSupport.stream(
        Spliterators.spliteratorUnknownSize(
            iterable.iterator(),
            Spliterator.ORDERED
        ),
        false
    );
}

इस समस्या के लिए एक बहुत ही सरल काम है एक Streamable<T> करने Streamable<T> इंटरफ़ेस विस्तार करने Iterable<T> जो एक default <T> stream() विधि रखता है।

interface Streamable<T> extends Iterable<T> {
    default Stream<T> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
}

अब आपके किसी भी Iterable<T> उन्हें implements Streamable<T> बजाय implements Streamable<T> घोषणा करके तुच्छ रूप से Iterable<T> किया जा सकता है।


मैं JOOL लाइब्रेरी का उपयोग करने का सुझाव देना चाहता हूं, यह Seq.seq (iterable) कॉल के पीछे स्प्लिटरेटर जादू छुपाता है और अतिरिक्त उपयोगी कार्यक्षमता का एक पूरा समूह भी प्रदान करता है।


मैंने इस वर्ग को बनाया है:

public class Streams {
    /**
     * Converts Iterable to stream
     */
    public static <T> Stream<T>  streamOf(final Iterable<T> iterable) {
        return toStream(iterable, false);
    }

    /**
     * Converts Iterable to parallel stream
     */
    public static <T> Stream<T> parallelStreamOf(final Iterable<T> iterable) {
        return toStream(iterable, true);
    }

    private static <T> Stream<T> toStream(final Iterable<T> iterable, final boolean isParallel) {
        return StreamSupport.stream(iterable.spliterator(), isParallel);
    }
}

मुझे लगता है कि यह पूरी तरह से पठनीय है क्योंकि आपको स्प्लिटरेटर्स और बूलियन (isParallel) के बारे में सोचना नहीं है।


यदि आप संस्करण 21 के बाद से गुवा पुस्तकालय का उपयोग कर सकते हैं, तो आप इसका उपयोग कर सकते हैं

Streams.stream(iterable)

spliteratorUnknownSize का उपयोग करने से कहीं अधिक बेहतर उत्तर है, जो दोनों आसान है और बेहतर परिणाम प्राप्त करता है। Iterable में एक spliterator() विधि है, इसलिए आपको बस अपना स्प्लिटरेटर प्राप्त करने के लिए इसका उपयोग करना चाहिए। सबसे बुरे मामले में, यह वही कोड (डिफ़ॉल्ट कार्यान्वयन spliteratorUnknownSize का उपयोग करता है), लेकिन अधिक सामान्य मामले में, जहां आपका Iterable पहले से ही एक संग्रह है, आपको एक बेहतर स्प्लिटरेटर मिलेगा, और इसलिए बेहतर स्ट्रीम प्रदर्शन (शायद यहां तक ​​कि समान समांतरता ।) यह भी कम कोड है:

StreamSupport.stream(iterable.spliterator(), false)
             .filter(...)
             .moreStreamOps(...);

जैसा कि आप देख सकते हैं, एक इटरटेबल से स्ट्रीम प्राप्त कर रहे हैं (देखें Iterable <T> स्ट्रीम () और समांतरस्ट्रीम () विधियों को क्यों प्रदान नहीं करता है? ) बहुत दर्दनाक नहीं है।





iterable