Filtrering av observerbare ting i RxJava

1. Introduksjon

Etter introduksjonen til RxJava skal vi se på filtreringsoperatørene.

Spesielt skal vi fokusere på filtrering, hopping, tidsfiltrering og noen mer avanserte filtreringsoperasjoner.

2. Filtrering

Når du jobber med Observerbar, noen ganger er det nyttig å velge bare et delsett av sendte elementer. For dette formålet, RxJava tilbyr forskjellige filtreringsmuligheter.

La oss begynne å se på filter metode.

2.1. De filter Operatør

Enkelt sagt, den filter operatøren filtrerer en Observerbar sørge for at utsendte gjenstander samsvarer med spesifisert tilstand, som kommer i form av en Predikere.

La oss se hvordan vi bare kan filtrere de merkelige verdiene fra de som sendes ut:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable .filter (i -> i% 2! = 0); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(1, 3, 5, 7, 9);

2.2. De ta Operatør

Når du filtrerer med ta, logikken resulterer i utslipp av den første n mens du ignorerer de gjenværende elementene.

La oss se hvordan vi kan filtrere kildeObserverbar og bare slipper de to første elementene:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.take (3); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(1, 2, 3);

2.3. De taMens Operatør

Når du bruker taMens de filtrerte Observerbar vil fortsette å sende ut ting til det møter et første element som ikke samsvarer med Predikere.

La oss se hvordan vi kan bruke taMens - med en filtrering Predikat:

Observable sourceObservable = Observable.just (1, 2, 3, 4, 3, 2, 1); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable .takeWhile (i -> i <4); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(1, 2, 3);

2.4. De taFørst Operatør

Når vi bare vil avgi det første elementet som samsvarer med en gitt tilstand, kan vi bruke det takeFirst ().

La oss se raskt på hvordan vi kan sende ut det første elementet som er større enn 5:

Observable sourceObservable = Observable .just (1, 2, 3, 4, 5, 7, 6); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable .takeFirst (x -> x> 5); filteredObservable.subscribe (abonnent); subscriber.assertValue (7);

2.5. først og firstOrDefault Operatører

En lignende oppførsel kan oppnås ved hjelp av først API:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.first (); filteredObservable.subscribe (abonnent); subscriber.assertValue (1);

Imidlertid, hvis vi vil spesifisere en standardverdi, kan vi bruke det hvis ingen elementer sendes ut firstOrDefault:

Observable sourceObservable = Observable.empty (); Observable filteredObservable = sourceObservable.firstOrDefault (-1); filteredObservable.subscribe (abonnent); subscriber.assertValue (-1);

2.6. De ta siste Operatør

Neste, hvis vi bare vil slippe ut det siste n gjenstander som sendes ut av en Observerbar, Vi kan bruke ta siste.

La oss se hvordan det er mulig å sende ut bare de tre siste elementene:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.takeLast (3); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(8, 9, 10);

Vi må huske at dette forsinker utslipp av noe fra kilden Observerbar til den er ferdig.

2.7. siste og lastOrDefault

Hvis vi bare vil sende ut det siste elementet, annet enn å bruke ta siste (1), Vi kan bruke siste.

Dette filtrerer Observerbar, bare sender ut det siste elementet, som eventuelt bekrefter en filtrering Predikere:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable .last (i -> i% 2! = 0); filteredObservable.subscribe (abonnent); subscriber.assertValue (9);

I tilfelle Observerbar er tom, kan vi bruke lastOrDefault, som filtrerer Observerbar sender ut standardverdien.

Standardverdien sendes også ut hvis lastOrDefault operatør brukes, og det er ikke noen elementer som bekrefter filtreringstilstanden:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.lastOrDefault (-1, i -> i> 10); filteredObservable.subscribe (abonnent); subscriber.assertValue (-1);

2.8. elementAt og elementAtOrDefault Operatører

Med elementAt operatør, kan vi velge et enkelt element som sendes ut av kilden Observerbar, spesifiserer indeksen:

Observable sourceObservable = Observable .just (1, 2, 3, 5, 7, 11); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.elementAt (4); filteredObservable.subscribe (abonnent); subscriber.assertValue (7);

Derimot, elementAt vil kaste en IndexOutOfBoundException hvis den angitte indeksen overstiger antall sendte artikler.

For å unngå denne situasjonen er det mulig å bruke elementAtOrDefault - som returnerer en standardverdi i tilfelle indeksen er utenfor området:

Observable sourceObservable = Observable .just (1, 2, 3, 5, 7, 11); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.elementAtOrDefault (7, -1); filteredObservable.subscribe (abonnent); subscriber.assertValue (-1);

2.9. De ofType Operatør

Når den Observerbar avgir Gjenstand elementer, er det mulig å filtrere dem basert på deres type.

La oss se hvordan vi bare kan filtrere String typeartikler som sendes ut:

Observable sourceObservable = Observable.just (1, "two", 3, "five", 7, 11); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.ofType (String.class); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​("to", "fem");

3. Hopp over

På den annen side, når vi vil filtrere ut eller hoppe over noen av elementene som sendes ut av en Observerbar, RxJava tilbyr noen få operatører som en motstykke til filtreringene, som vi tidligere har diskutert.

La oss begynne å se på hopp over operatør, motstykket til ta.

3.1. De hopp over Operatør

Når en Observerbar sender ut en sekvens med elementer, er det mulig å filtrere ut eller hoppe over noen av de først sendte elementene ved hjelp av hopp over.

For eksempel. la oss se hvordan det er mulig å hoppe over de første fire elementene:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.skip (4); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(5, 6, 7, 8, 9, 10);

3.2. De hopp over Operatør

Når vi ønsker å filtrere ut alle de første verdiene som sendes ut av en Observerbar som ikke klarer et filtreringspredikat, kan vi bruke hopp over operatør:

Observable sourceObservable = Observable .just (1, 2, 3, 4, 5, 4, 3, 2, 1); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable .skipWhile (i -> i <4); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(4, 5, 4, 3, 2, 1);

3.3. De skipLast Operatør

De skipLast lar oss hoppe over de endelige elementene som sendes ut av Observerbar aksepterer bare de som er sluppet ut før dem.

Med dette kan vi for eksempel hoppe over de fem siste elementene:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = sourceObservable.skipLast (5); filteredObservable.subscribe (abonnent); subscriber.assertValues ​​(1, 2, 3, 4, 5);

3.4. distinkt og distinktUntilChanged Operatører

De distinkt operatøren returnerer en Observerbar som sender ut alle elementene som sendes ut av kildeObservabel som er forskjellige:

Observable sourceObservable = Observable .just (1, 1, 2, 2, 1, 3, 3, 1); TestSubscriber-abonnent = ny TestSubscriber (); Observable distinctObservable = sourceObservable.distinct (); distinctObservable.subscribe (abonnent); subscriber.assertValues ​​(1, 2, 3);

Imidlertid, hvis vi ønsker å få en Observerbar som sender ut alle elementene som sendes ut av kildeObservabel som er forskjellige fra deres nærmeste forgjenger, kan vi bruke distinktUntilChanged operatør:

Observable sourceObservable = Observable .just (1, 1, 2, 2, 1, 3, 3, 1); TestSubscriber-abonnent = ny TestSubscriber (); Observable distinctObservable = sourceObservable.distinctUntilChanged (); distinctObservable.subscribe (abonnent); subscriber.assertValues ​​(1, 2, 1, 3, 1);

3.5. De ignorere elementer Operatør

Når vi vil ignorere alle elementene som sendes ut av kildeObservabel, kan vi ganske enkelt bruke ignorere elementer:

Observable sourceObservable = Observable.range (1, 10); TestSubscriber-abonnent = ny TestSubscriber (); Observable ignoredObservable = sourceObservable.ignoreElements (); ignoredObservable.subscribe (abonnent); subscriber.assertNoValues ​​();

4. Tidsfiltreringsoperatører

Når du jobber med observerbar sekvens, er tidsaksen ukjent, men noen ganger kan det være nyttig å få data fra en sekvens i tide.

Med dette formålet, RxJava tilbyr noen få metoder som lar oss jobbe med Observerbar bruker også tidsaksen.

Før vi går videre til den første, la oss definere en tidsbestemt tid Observerbar som sender ut et element hvert sekund:

TestScheduler testScheduler = ny TestScheduler (); Observable timedObservable = Observable .just (1, 2, 3, 4, 5, 6) .zipWith (Observable.interval (0, 1, TimeUnit.SECONDS, testScheduler), (item, time) -> item);

De Testplanlegger er en spesiell planlegger som gjør det mulig å fremme klokken manuelt uansett hvilket tempo vi foretrekker.

4.1. prøve og gass ​​sist Operatører

De prøve operatøren filtrerer timedObservable, returnerer en Observerbar som sender ut de siste elementene som sendes ut av denne API-en innen tidsperioder.

La oss se hvordan vi kan prøve timedObservable, filtrerer bare det sist sendte elementet hvert 2,5 sekund:

TestSubscriber-abonnent = ny TestSubscriber (); Observable sampledObservable = timedObservable .sample (2500L, TimeUnit.MILLISECONDS, testScheduler); sampledObservable.subscribe (abonnent); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues ​​(3, 5, 6);

Denne typen oppførsel kan oppnås også ved hjelp av gass ​​sist operatør.

4.2. De gasspjeld Først Operatør

De gasspjeld Først operatøren skiller seg fra gasspjeld siste / prøve siden den avgir det første elementet som sendes ut av timedObservable i hver prøvetidsperiode i stedet for den sist sendte.

La oss se hvordan vi kan sende ut de første elementene, ved hjelp av en prøvetidsperiode på 4 sekunder:

TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = timedObservable .throttleFirst (4100L, TimeUnit.SECONDS, testScheduler); filteredObservable.subscribe (abonnent); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues ​​(1, 6);

4.3. avvise og gasspjeldWithTimeout Operatører

Med avvise operatør, er det mulig å kun sende ut et element hvis et bestemt tidsrom har gått uten å sende ut et annet element.

Derfor, hvis vi velger et tidsrom som er større enn tidsintervallet mellom de sendte elementene i timedObservable, vil den bare avgi den siste. På den annen side, hvis den er mindre, vil den sende ut alle elementene som sendes ut av timedObservable.

La oss se hva som skjer i det første scenariet:

TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = timedObservable .debounce (2000L, TimeUnit.MILLISECONDS, testScheduler); filteredObservable.subscribe (abonnent); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValue (6);

Denne typen oppførsel kan også oppnås ved hjelp av gasspjeldWithTimeout.

4.4. De pause Operatør

De pause operatøren speiler kilden Observerbar, men send en varslingsfeil, og avbryt utslipp av gjenstander, hvis kilden Observerbar unnlater å sende ut noen gjenstander i et spesifisert tidsintervall.

La oss se hva som skjer hvis vi spesifiserer en timeout på 500 millisekunder til vår timedObservable:

TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = timedObservable .timeout (500L, TimeUnit.MILLISECONDS, testScheduler); filteredObservable.subscribe (abonnent); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertError (TimeoutException.class); subscriber.assertValues ​​(1);

5. Flere observerbare filtreringer

Når du jobber med Observerbar, er det definitivt mulig å avgjøre om filtrering eller hopping av varer er basert på et sekund Observerbar.

Før vi går videre, la oss definere en forsinketObservabel, som bare sender ut 1 element etter 3 sekunder:

Observable delayedObservable = Observable.just (1) .delay (3, TimeUnit.SECONDS, testScheduler);

La oss starte med ta til operatør.

5.1. De ta til Operatør

De ta til operatøren kaster alle gjenstander som sendes ut av kilden Observerbar (timedObservable) etter et sekund Observerbar (forsinketObservabel) sender ut en vare eller avslutter:

TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = timedObservable .skipUntil (delayedObservable); filteredObservable.subscribe (abonnent); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues ​​(4, 5, 6);

5.2. De hoppe til Operatør

På den andre siden, hoppe til kaster alle gjenstander som slippes ut av kilden Observerbar (timedObservable) til et sekund Observerbar (forsinketObservabel) sender ut et element:

TestSubscriber-abonnent = ny TestSubscriber (); Observable filteredObservable = timedObservable .takeUntil (delayedObservable); filteredObservable.subscribe (abonnent); testScheduler.advanceTimeBy (7, TimeUnit.SECONDS); subscriber.assertValues ​​(1, 2, 3);

6. Konklusjon

I denne omfattende opplæringen utforsket vi de forskjellige filtreringsoperatørene som er tilgjengelige i RxJava, og gir et enkelt eksempel på hver enkelt.

Som alltid kan alle kodeeksemplene i denne artikkelen finnes på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found