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.