क्या Java 8 धाराएँ RxJava वेधशालाओं के समान हैं?
जावा 8 स्ट्रीम परिभाषा:
नए
java.util.stream
पैकेज में कक्षाएं तत्वों की धाराओं पर कार्यात्मक-शैली के संचालन का समर्थन करने के लिए एक स्ट्रीम एपीआई प्रदान करती हैं।
क्या Java 8 धाराएँ RxJava वेधशालाओं के समान हैं?
जावा 8 स्ट्रीम परिभाषा:
नए
java.util.stream
पैकेज में कक्षाएं तत्वों की धाराओं पर कार्यात्मक-शैली के संचालन का समर्थन करने के लिए एक स्ट्रीम एपीआई प्रदान करती हैं।
जवाबों:
टीएल; डीआर : सभी अनुक्रम / स्ट्रीम प्रोसेसिंग लिबास पाइपलाइन बिल्डिंग के लिए बहुत समान एपीआई की पेशकश कर रहे हैं। बहु-थ्रेडिंग और पाइपलाइनों की संरचना से निपटने के लिए एपीआई एपीआई में हैं।
RxJava, स्ट्रीम से काफी अलग है। सभी JDK चीजों में से, rx.Observable के सबसे करीब शायद java.util.stream.Collector Stream + CompletableFuture कॉम्बो है (जो अतिरिक्त मोनाड परत से निपटने की लागत पर आता है, यानी बीच में संभाल करने के लिए Stream<CompletableFuture<T>>
और CompletableFuture<Stream<T>>
)।
अवलोकन और धारा के बीच महत्वपूर्ण अंतर हैं:
Stream#parallel()
विभाजन में अनुक्रम विभाजित करता है, Observable#subscribeOn()
और Observable#observeOn()
नहीं; Stream#parallel()
ऑब्जर्वबल के साथ व्यवहार का अनुकरण करना मुश्किल है , यह एक बार .parallel()
विधि थी लेकिन इस पद्धति ने इतना भ्रम पैदा किया कि .parallel()
समर्थन को जीथब, आरएक्सजवापेरल पर अलग रिपॉजिटरी में स्थानांतरित कर दिया गया। अधिक विवरण एक और उत्तर में हैं ।Stream#parallel()
वैकल्पिक शेड्यूलर को स्वीकार करने वाले अधिकांश RxJava तरीकों के विपरीत, एक थ्रेड पूल का उपयोग करने की अनुमति नहीं देता है। चूंकि JVM में सभी स्ट्रीम इंस्टेंस एक ही कांटे-जुड़ने वाले पूल का उपयोग करते हैं, इसलिए .parallel()
गलती से आपके प्रोग्राम के दूसरे मॉड्यूल में व्यवहार को प्रभावित कर सकते हैंObservable#interval()
, जैसे Observable#window()
और कई अन्य; यह ज्यादातर इसलिए है क्योंकि स्ट्रीम पुल-आधारित हैं, और अपस्ट्रीम का कोई नियंत्रण नहीं है कि अगले तत्व डाउनस्ट्रीम का उत्सर्जन कब करना हैtakeWhile()
, takeUntil()
) की कमी है ; वर्कअराउंड का उपयोग Stream#anyMatch()
सीमित है: यह टर्मिनल ऑपरेशन है, इसलिए आप इसे प्रति स्ट्रीम एक से अधिक बार उपयोग नहीं कर सकतेObservable#using()
); आप इसके साथ IO स्ट्रीम या म्यूटेक्स को लपेट सकते हैं और सुनिश्चित करें कि उपयोगकर्ता संसाधन को मुक्त करना नहीं भूलेंगे - यह सदस्यता समाप्ति पर स्वचालित रूप से निपटाया जाएगा; स्ट्रीम में onClose(Runnable)
विधि है, लेकिन आपको इसे मैन्युअल रूप से या कोशिश-के-संसाधनों के माध्यम से कॉल करना होगा। ई। जी। आपको यह ध्यान रखना होगा कि फ़ाइलें # लाइनों () को प्रयास-से-संसाधन ब्लॉक में संलग्न होना चाहिए।राउंड-अप: RxJava स्ट्रीम से काफी अलग है। वास्तविक RxJava विकल्प रिएक्टिवस्ट्रीम के अन्य कार्यान्वयन हैं , जैसे अक्का का प्रासंगिक हिस्सा।
अद्यतन करें । गैर-डिफ़ॉल्ट कांटा-जुड़ने वाले पूल का उपयोग करने के लिए ट्रिक है Stream#parallel
, जावा 8 समानांतर स्ट्रीम में कस्टम थ्रेड पूल देखें
अद्यतन करें । उपरोक्त सभी RxJava 1.x के अनुभव पर आधारित है। अब जब RxJava 2.x यहाँ है , तो यह उत्तर पुराना हो सकता है।
Stream.generate()
अपने स्वयं के Supplier<U>
कार्यान्वयन को कॉल और पास कर सकते हैं , बस एक सरल विधि जिससे आप स्ट्रीम में अगला आइटम प्रदान करते हैं। अन्य तरीकों के भार हैं। आसानी से एक अनुक्रम का निर्माण करने के लिए Stream
जो पिछले मूल्यों पर निर्भर करता है आप interate()
विधि का उपयोग कर सकते हैं , प्रत्येक Collection
में एक stream()
विधि है और एक varargs या सरणी से Stream.of()
निर्माण करता Stream
है। अंत StreamSupport
में Spliterators का उपयोग करके या स्ट्रीम आदिम प्रकारों के लिए अधिक उन्नत स्ट्रीम निर्माण के लिए समर्थन है।
takeWhile()
, takeUntil()
);" का अभाव है । - JDK9 में ये हैं, मुझे विश्वास है, टेकवाइल में () और ड्रॉपव्हील ()
Java 8 स्ट्रीम और RxJava काफी समान दिखते हैं। उनके पास एक जैसे दिखने वाले ऑपरेटर (फ़िल्टर, मानचित्र, फ़्लैटमैप ...) हैं, लेकिन समान उपयोग के लिए नहीं बनाए गए हैं।
आप RxJava का उपयोग करके एसिंकोनस कार्य कर सकते हैं।
जावा 8 स्ट्रीम के साथ, आप अपने संग्रह की वस्तुओं को पार करेंगे।
आप RxJava (संग्रह के आइटम) में समान काम कर सकते हैं, लेकिन जैसे RxJava समवर्ती कार्य पर ध्यान केंद्रित किया जाता है, ..., यह सिंक्रनाइज़ेशन, कुंडी का उपयोग करता है, ... इसलिए RJJava का उपयोग करने वाला एक ही कार्य धीमा हो सकता है जावा 8 स्ट्रीम के साथ।
RxJava की तुलना की जा सकती है CompletableFuture
, लेकिन यह केवल एक मूल्य से अधिक गणना करने में सक्षम हो सकता है।
parallelStream
सरल ट्रैवर्सल्स / मैप्स / फ़िल्टरिंग आदि के समान तुल्यकालन का समर्थन करता है ..
उदाहरण के लिए, कुछ तकनीकी और वैचारिक भिन्नताएं हैं, उदाहरण के लिए, जावा 8 स्ट्रीम एकल उपयोग, पुल आधारित, मूल्यों के समकालिक अनुक्रम हैं जबकि RxJava वेधशालाएँ पुन: अवलोकन योग्य, अनुकूली पुश-पुल आधारित, संभावित रूप से अतुल्यकालिक अनुक्रम मान हैं। RxJava का लक्ष्य जावा 6+ है और यह एंड्रॉइड पर भी काम करता है।
जावा 8 स्ट्रीम पुल आधारित हैं। आप प्रत्येक आइटम का उपभोग करने वाले जावा 8 स्ट्रीम पर पुनरावृति करते हैं। और यह एक अंतहीन धारा हो सकती है।
RXJava Observable
डिफ़ॉल्ट पुश आधारित है। आप एक ऑब्जर्वेबल की सदस्यता लेते हैं और अगले आइटम के आने ( onNext
), या जब धारा पूरी हो जाती है ( onCompleted
), या जब एक त्रुटि हुई (तब) आपको सूचित किया जाएगा onError
। क्योंकि के साथ Observable
आपको प्राप्त onNext
, onCompleted
,onError
घटनाओं, आप कुछ शक्तिशाली कार्यों अलग संयोजन की तरह कर सकते हैं Observable
एक नया एक के लिए है ( zip
, merge
, concat
)। अन्य सामान जो आप कर सकते थे, कैशिंग, थ्रॉटलिंग, ... और यह कमोबेश एक ही एपीआई का उपयोग विभिन्न भाषाओं में (RxJava, RX in C #, RxJS, ...) करता है।
डिफ़ॉल्ट रूप से RxJava सिंगल थ्रेडेड है। जब तक आप शेड्यूलर्स का उपयोग शुरू नहीं करते हैं, तब तक सब कुछ एक ही धागे पर होगा।
मौजूदा उत्तर व्यापक और सही हैं, लेकिन शुरुआती लोगों के लिए एक स्पष्ट उदाहरण की कमी है। मुझे "पुश / पुल-बेस्ड" और "री-ऑब्जर्वेबल" जैसे शब्दों के पीछे कुछ ठोस डालने की अनुमति दें। नोट : मैं पद से नफरत करता हूं Observable
(यह स्वर्ग के लिए एक धारा है), इसलिए बस जे 8 बनाम आरएक्स धाराओं का उल्लेख करेगा।
पूर्णांकों की सूची पर विचार करें,
digits = [1,2,3,4,5]
एक J8 स्ट्रीम संग्रह को संशोधित करने के लिए एक उपयोगिता है। उदाहरण के लिए अंक भी निकाले जा सकते हैं,
evens = digits.stream().filter(x -> x%2).collect(Collectors.toList())
यह मूल रूप से पायथन का नक्शा, फ़िल्टर, कम करना है से जावा के अलावा , एक बहुत अच्छा (और लंबी अतिदेय) है। लेकिन क्या होगा अगर अंकों को समय से पहले एकत्र नहीं किया गया था - क्या होगा यदि एप्लिकेशन चलने के दौरान अंक स्ट्रीमिंग थे - क्या हम वास्तविक समय में भी फ़िल्टर कर सकते हैं।
एक अलग थ्रेड प्रक्रिया की कल्पना करें कि ऐप चल रहा है, जबकि यादृच्छिक समय पर पूर्णांक आउटपुट कर रहा है ( ---
समय दर्शाता है)
digits = 12345---6------7--8--9-10--------11--12
आरएक्स में, प्रत्येक नए अंक पर प्रतिक्रियाeven
कर सकते हैं और वास्तविक समय में फ़िल्टर लागू कर सकते हैं
even = -2-4-----6---------8----10------------12
इनपुट और आउटपुट सूचियों को संग्रहीत करने की कोई आवश्यकता नहीं है। यदि आप एक आउटपुट सूची चाहते हैं , तो कोई समस्या नहीं जो सुव्यवस्थित भी हो। वास्तव में, सब कुछ एक धारा है।
evens_stored = even.collect()
यही कारण है कि "स्टेटलेस" और "फंक्शनल" जैसे शब्द आरएक्स से अधिक जुड़े हुए हैं
RxJava भी प्रतिक्रियाशील धाराओं की पहल से निकटता से संबंधित है और इसे स्वयं को प्रतिक्रियाशील धाराओं एपीआई (जैसे अक्का धाराओं के कार्यान्वयन की तुलना में ) के एक सरल कार्यान्वयन के रूप में मानता है । मुख्य अंतर यह है, कि प्रतिक्रियाशील धाराएं दबाव को संभालने में सक्षम होने के लिए डिज़ाइन की गई हैं, लेकिन यदि आप प्रतिक्रियाशील धाराओं पृष्ठ पर एक नज़र डालते हैं, तो आपको विचार मिलेगा। वे अपने लक्ष्यों का बहुत अच्छी तरह से वर्णन करते हैं और धाराएं प्रतिक्रियात्मक घोषणापत्र से भी निकटता से संबंधित हैं ।
जावा 8 धाराएँ एक अनबिके संग्रह के कार्यान्वयन के लिए बहुत ज्यादा हैं, जो कि स्काला स्ट्रीम या क्लोजर आलसी फक के समान है ।
जावा 8 स्ट्रीम मल्टीकोर आर्किटेक्चर का लाभ उठाते हुए वास्तव में बड़े संग्रह के प्रसंस्करण को सक्षम बनाता है। इसके विपरीत, RxJava डिफ़ॉल्ट रूप से (शेड्यूलर के बिना) थ्रेडेड है। इसलिए RxJava मल्टी-कोर मशीनों का लाभ नहीं उठाएगा जब तक कि आप उस तर्क को स्वयं कोड न करें।