Megfigyelhető anyagok szűrése az RxJava-ban
1. Bemutatkozás
Az RxJava bevezetését követően megnézzük a szűrési operátorokat.
Különösen a szűrésre, az átugrásra, az időszűrésre és néhány fejlettebb szűrési műveletre fogunk összpontosítani.
2. Szűrés
Amikor dolgozik Megfigyelhető, néha hasznos csak a kibocsájtott elemek egy részét kiválasztani. Erre a célra, Az RxJava különféle szűrési lehetőségeket kínál.
Kezdjük nézegetni a szűrő módszer.
2.1. A szűrő Operátor
Egyszerűen fogalmazva: szűrő operátor szűr egy an Megfigyelhető győződjön meg arról, hogy a kibocsátott elemek megfelelnek-e a megadott feltételnek, amely a formájában jelenik meg Állítmány.
Lássuk, hogyan tudjuk csak a páratlan értékeket kiszűrni a kibocsátott értékekből:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable .filter (i -> i% 2! = 0); filteredObservable.subscribe (előfizető); subscriber.assertValues (1, 3, 5, 7, 9);
2.2. A vesz Operátor
A szűréssel vesz, a logika az első emisszióját eredményezi n elemeket, miközben figyelmen kívül hagyja a többi elemet.
Lássuk, hogyan tudjuk kiszűrni a forrásMegfigyelhető és csak az első két elemet bocsátja ki:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.take (3); filteredObservable.subscribe (előfizető); subscriber.assertValues (1, 2, 3);
2.3. A vegyeMíg Operátor
Használat során takeWhile, a szűrt Megfigyelhető addig bocsát ki elemeket, amíg meg nem talál egy első elemet, amely nem felel meg a Állítmány.
Lássuk, hogyan használhatjuk a vegyeMíg - szűréssel Állítmány:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető. Csak (1, 2, 3, 4, 3, 2, 1); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable .takeWhile (i -> i <4); filteredObservable.subscribe (előfizető); subscriber.assertValues (1, 2, 3);
2.4. A takeFirst Operátor
Amikor csak egy adott feltételnek megfelelő első tételt akarunk kiadni, használhatjuk takeFirst ().
Nézzük meg gyorsan, hogyan bocsáthatjuk ki az első 5-nél nagyobb elemet:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető .just (1, 2, 3, 4, 5, 7, 6); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable .takeFirst (x -> x> 5); filteredObservable.subscribe (előfizető); subscriber.assertValue (7);
2.5. első és firstOrDefault Operátorok
Hasonló viselkedés érhető el a első API:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.first (); filteredObservable.subscribe (előfizető); subscriber.assertValue (1);
Abban az esetben azonban, ha meg akarunk adni egy alapértelmezett értéket, és ha nem adunk ki elemeket, használhatjuk firstOrDefault:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető. Üres (); Megfigyelhető filteredObservable = sourceObservable.firstOrDefault (-1); filteredObservable.subscribe (előfizető); subscriber.assertValue (-1);
2.6. A takeLast Operátor
Ezután, ha csak az utolsót akarjuk kibocsátani n által kibocsátott tárgyak Megfigyelhető, tudjuk használni takeLast.
Nézzük meg, hogyan lehetséges csak az utolsó három elem kibocsátása:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.takeLast (3); filteredObservable.subscribe (előfizető); subscriber.assertValues (8, 9, 10);
Emlékeznünk kell arra, hogy ez késlelteti bármely tétel kibocsátását a forrásból Megfigyelhető amíg be nem fejeződik.
2.7. utolsó és lastOrDefault
Ha csak az utolsó elemet akarjuk kiadni, akkor más, mint a takeLast (1), tudjuk használni utolsó.
Ez szűri a Megfigyelhető, csak az utolsó elemet bocsátja ki, amely opcionálisan ellenőrzi a szűrést Állítmány:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable .last (i -> i% 2! = 0); filteredObservable.subscribe (előfizető); subscriber.assertValue (9);
Abban az esetben, ha a Megfigyelhető üres, használhatjuk lastOrDefault, amely szűri a Megfigyelhető az alapértelmezett érték kibocsátása.
Az alapértelmezett érték akkor is kibocsátásra kerül, ha a lastOrDefault operátort használunk, és nincs olyan elem, amely ellenőrizné a szűrési feltételt:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.lastOrDefault (-1, i -> i> 10); filteredObservable.subscribe (előfizető); subscriber.assertValue (-1);
2.8. elemAt és elemAtOrDefault Operátorok
A ... val elemAt operátor, kiválaszthatunk egyetlen elemet, amelyet a forrás bocsát ki Megfigyelhető, megadva az indexét:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető .just (1, 2, 3, 5, 7, 11); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.elementAt (4); filteredObservable.subscribe (előfizető); subscriber.assertValue (7);
Azonban, elemAt dobni fog egy IndexOutOfBoundException ha a megadott index meghaladja a kibocsátott tételek számát.
Ennek elkerülése érdekében lehetséges elementAtOrDefault - amely az alapértelmezett értéket adja vissza abban az esetben, ha az index a tartományon kívül esik:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető .just (1, 2, 3, 5, 7, 11); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.elementAtOrDefault (7, -1); filteredObservable.subscribe (előfizető); subscriber.assertValue (-1);
2.9. A ofType Operátor
Valahányszor a Megfigyelhető kibocsájt Tárgy elemeket, típusuk alapján lehet szűrni.
Lássuk, hogyan tudjuk csak a Húr típusú kibocsátott elemek:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető. Csak (1, "kettő", 3, "öt", 7, 11); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.ofType (String.class); filteredObservable.subscribe (előfizető); subscriber.assertValues ("kettő", "öt");
3. Ugrás
Másrészt, amikor ki akarjuk szűrni vagy kihagyni az an által kibocsátott elemek egy részét Megfigyelhető, Az RxJava néhány operátort kínál a szűrők párjaként, amelyet korábban megbeszéltünk.
Kezdjük nézegetni a kihagy üzemeltető, a vesz.
3.1. A kihagy Operátor
Amikor egy Megfigyelhető tételsorozatot bocsát ki, az első segítségével kibocsátott elemek egy részét kiszűrheti vagy kihagyhatja kihagy.
Például. nézzük meg, hogyan lehet kihagyni az első négy elemet:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.skip (4); filteredObservable.subscribe (előfizető); subscriber.assertValues (5, 6, 7, 8, 9, 10);
3.2. A skipWhile Operátor
Amikor ki akarjuk szűrni az első által kibocsátott összes első értéket Megfigyelhető amelyek nem felelnek meg egy szűrési predikátumnak, használhatjuk a skipWhile operátor:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető .just (1, 2, 3, 4, 5, 4, 3, 2, 1); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable .skipWhile (i -> i <4); filteredObservable.subscribe (előfizető); subscriber.assertValues (4, 5, 4, 3, 2, 1);
3.3. A skipLast Operátor
A skipLast operátor lehetővé teszi számunkra, hogy kihagyjuk a Megfigyelhető csak az előttük kibocsátottakat fogadja el.
Ezzel például kihagyhatjuk az utolsó öt elemet:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = sourceObservable.skipLast (5); filteredObservable.subscribe (előfizető); subscriber.assertValues (1, 2, 3, 4, 5);
3.4. különböző és differentUntilChanged Operátorok
A különböző az operátor visszaad egy Megfigyelhető amely kibocsájtja a forrásMegfigyelhető amelyek különböznek:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető .just (1, 1, 2, 2, 1, 3, 3, 1); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető megkülönböztethető = forrásMegfigyelhető.különbség (); differentObservable.subscribe (előfizető); subscriber.assertValues (1, 2, 3);
Ha azonban egy Megfigyelhető amely kibocsátja az összes által kibocsátott tételt forrásMegfigyelhető amelyek különböznek közvetlen elődjüktől, használhatjuk a differentUntilChanged operátor:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető .just (1, 1, 2, 2, 1, 3, 3, 1); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető differentObservable = sourceObservable.distinctUntilChanged (); differentObservable.subscribe (előfizető); subscriber.assertValues (1, 2, 1, 3, 1);
3.5. A ignoreElements Operátor
Valahányszor figyelmen kívül akarjuk hagyni a forrásMegfigyelhető, egyszerűen használhatjuk a ignoreElements:
Megfigyelhető forrás: Megfigyelhető = Megfigyelhető.tartomány (1, 10); TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető ignoreObservable = sourceObservable.ignoreElements (); ignoredObservable.subscribe (előfizető); előfizető.assertNoValues ();
4. Időszűrő operátorok
Megfigyelhető sorrenddel történő munka esetén az idő tengely ismeretlen, de néha hasznos lehet egy szekvencia időben történő megszerzése.
Ezzel a céllal Az RxJava néhány módszert kínál, amelyek lehetővé teszik számunkra a munkát Megfigyelhető az idő tengelyét is felhasználva.
Mielőtt továbblépnénk az elsőre, határozzunk meg egy időzítést Megfigyelhető amely másodpercenként tételt bocsát ki:
TestScheduler testScheduler = új TestScheduler (); Megfigyelhető timedObservable = Megfigyelhető .just (1, 2, 3, 4, 5, 6) .zipWith (Megfigyelhető.interval (0, 1, TimeUnit.SECONDS, testScheduler), (elem, idő) -> elem);
A TestScheduler egy speciális ütemező, amely lehetővé teszi az óra manuális előrehaladását bármilyen tempóban preferáljuk.
4.1. minta és fojtószelepUtolsó Operátorok
A minta operátor szűri a időzítveMegfigyelhető, visszaadva egy Megfigyelhető amely időszakos időközönként bocsátja ki az API által kiadott legfrissebb elemeket.
Lássuk, hogyan állíthatjuk be a mintát időzítveMegfigyelhető, 2,5 másodpercenként csak az utoljára kibocsátott elem szűrése:
TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető mintavételObservable = timedObservable .sample (2500L, TimeUnit.MILLISECONDS, testScheduler); sampledObservable.subscribe (előfizető); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues (3, 5, 6);
Ez a fajta viselkedés a fojtószelepUtolsó operátor.
4.2. A fojtószelep Először Operátor
A fojtószelep Először operátor eltér throttleLast / minta mivel kibocsátja az első által kibocsátott tételt időzítveMegfigyelhető minden mintavételi periódusban a legutóbb kibocsátott helyett.
Nézzük meg, hogyan bocsáthatjuk ki az első elemeket 4 másodperces mintavételi periódus használatával:
TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = timedObservable .throttleFirst (4100L, TimeUnit.SECONDS, testScheduler); filteredObservable.subscribe (előfizető); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues (1, 6);
4.3. visszadobni és throttleWithTimeout Operátorok
A ... val visszadobni operátor, akkor csak akkor lehet kibocsátani egy elemet, ha egy adott időintervallum eltelt anélkül, hogy másik elemet kibocsátott volna.
Ezért, ha olyan időtartamot választunk, amely nagyobb, mint a időzítveMegfigyelhető, csak az utolsót bocsátja ki. Másrészt, ha kisebb, akkor az összes által kibocsátott tételt kibocsátja időzítveMegfigyelhető.
Lássuk, mi történik az első forgatókönyvben:
TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = timedObservable .debounce (2000L, TimeUnit.MILLISECONDS, testScheduler); filteredObservable.subscribe (előfizető); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValue (6);
Ez a fajta viselkedés a throttleWithTimeout.
4.4. A időtúllépés Operátor
A időtúllépés operátor tükrözi a forrást Megfigyelhető, de kiad egy értesítési hibát, megszakítva az elemek kibocsátását, ha a forrás Megfigyelhető egy adott időintervallum alatt nem bocsát ki elemeket.
Lássuk, mi történik, ha 500 milliszekundumos időtúllépést határozunk meg időzítveMegfigyelhető:
TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = timedObservable .timeout (500L, TimeUnit.MILLISECONDS, testScheduler); filteredObservable.subscribe (előfizető); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertError (TimeoutException.class); subscriber.assertValues (1);
5. Többszörös megfigyelhető szűrés
Amikor dolgozik Megfigyelhető, mindenképpen el lehet dönteni, hogy az elemek szűrése vagy kihagyása egy másodperc alapján történik-e Megfigyelhető.
Mielőtt továbblépnénk, definiáljuk a késleltethető. Megfigyelhető, amely 3 másodperc után csak 1 elemet bocsát ki:
Megfigyelhető delayedObservable = Megfigyelhető.just (1) .delay (3, TimeUnit.SECONDS, testScheduler);
Kezdjük azzal takeUntil operátor.
5.1. A takeUntil Operátor
A takeUntil az operátor eldob minden, a forrás által kibocsátott tételt Megfigyelhető (időzítveMegfigyelhető) egy másodperc után Megfigyelhető (késleltethető. Megfigyelhető) tételt bocsát ki vagy megszünteti:
TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = timedObservable .skipUntil (delayedObservable); filteredObservable.subscribe (előfizető); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues (4, 5, 6);
5.2. A skipUntil Operátor
Másrészről, skipUntil a forrás által kibocsátott tárgyakat elveti Megfigyelhető (időzítveMegfigyelhető) egy másodpercig Megfigyelhető (késleltethető. Megfigyelhető) tételt bocsát ki:
TestSubscriber előfizető = new TestSubscriber (); Megfigyelhető filteredObservable = timedObservable .takUntil (delayedObservable); filteredObservable.subscribe (előfizető); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues (1, 2, 3);
6. Következtetés
Ebben a kiterjedt oktatóanyagban megvizsgáltuk az RxJava-ban elérhető különböző szűrési operátorokat, mindegyikükre egyszerű példát adva.
Mint mindig, a cikk összes kódpéldája megtalálható a GitHubon.