RxJava development requires 4-Observables Filtering

Source: Internet
Author: User
Tags emit

RxJava development requires 4-Observables Filtering
Filter Observables

In the previous chapter, we learned how to use RxJava to create an Android project and how to create an observability list to populate the RecyclerView. We now know how to create an Observable from the beginning, from the list, from an existing traditional Java function.

In this chapter, we will study the nature of the observability sequence: filtering. We will learn how to select the expected value from the transmitted Observable, how to obtain a limited number of values, how to handle overflow scenarios, and more useful techniques.

Filter Sequence

RxJava lets us usefilter()Method to filter out the values that we do not want in the observed sequence. in the previous chapter, we used the list of installed applications in several examples, but we only want to display the values with lettersCWhat should I do if I start with an installed application? In this new example, we will use the same list, but we will filter it and pass the appropriate predicatesfilter()Function to obtain the expected value.

In the previous chapterloadList()The function can be changed to the following:

private void loadList(List apps) {    mRecyclerView.setVisibility(View.VISIBLE);    Observable.from(apps)            .filter((appInfo) ->            appInfo.getName().startsWith("C"))            .subscribe(new Observable() {                @Override                public void onCompleted() {                    mSwipeRefreshLayout.setRefreshing(false);                }                @Override                public void onError(Throwable e) {                    Toast.makeText(getActivity(), "Something went wrong!", Toast.LENGTH_SHORT).show();                    mSwipeRefreshLayout.setRefreshing(false);                }                @Override                public void onNext(AppInfo appInfo) {                    mAddedApps.add(appInfo);                     mAdapter.addApplication(mAddedApps.size() - 1,appInfo);                }            });}

FromloadList()Add the following line to the function:

.fliter((appInfo -> appInfo.getName().startsWith("C"))

After creating the Observable, We can filter out each element from which the starting letter is not C. To make it clearer, we use the Java 7 Syntax:

.filter(new Func1(){    @Override    public Boolean call(AppInfo appInfo){        return appInfo.getName().startsWith("C");    }})

Let's upload a newFunc1Objectfilter()Function, that is, a function with only one parameter.Func1There isAppInfoObject as its parameter type and returnsBooleanObject. As long as the conditions meetfilter()The function returnstrue. At this time, the value will be sent out and all the observers will receive it.

As you think, create a sequence we need from an observed sequence.filter()Is very useful. We don't need to know the source of the observed sequence or why so many different data is sent. We just want a subset of these elements to create a new sequence that can be used in the application. This idea promotes the separation and abstraction in our code.

filter()One-time filtering in the most common usage of functionsnullObject:

.filter(new Func1(){    @Override    public Boolean call(AppInfo appInfo){        return appInfo != null;    }})

This looks simple. There are a lot of template code for simple things, but it helps us avoidonNext()Function call before detectionnullValue, let us focus on the application business logic.

Displays the list of installed applications starting with the filtered C Letter.

Get the data we need

When we do not need the whole sequence, we only want to take the elements at the beginning or end. We can usetake()OrtakeLast().

Take

What would happen if we only wanted the first three elements in a sequence that could be observed? Would it be possible to launch them and then let the Observable complete?take()The function uses integer N as a parameter to transmit the first N elements from the original sequence, and then completes:

private void loadList(List apps) {    mRecyclerView.setVisibility(View.VISIBLE);    Observable.from(apps)            .take(3)            .subscribe(new Observable() {                @Override                public void onCompleted() {                    mSwipeRefreshLayout.setRefreshing(false);                }                @Override                public void onError(Throwable e) {                    Toast.makeText(getActivity(), "Something went wrong!", Toast.LENGTH_SHORT).show();                    mSwipeRefreshLayout.setRefreshing(false);                }                @Override                public void onNext(AppInfo appInfo) {                    mAddedApps.add(appInfo);                     mAdapter.addApplication(mAddedApps.size() - 1,appInfo);                }            });}

It shows an observed sequence of emission numbers. We apply this observability Sequencetake(2)Then we create a new sequence that only emits the first and second data of the observed source.

TakeLast

If we want the last N elements, we only need to usetakeLast()Function:

Observable.from(apps)        .takeLast(3)        .subscribe(https://github.com/yuxingxin/RxJava-Essentials-CN/raw/master.);

As it sounds not worth mentioning, pay attentiontakeLast()Because a function uses the essence of a finite number of emission, it can be used only for complete sequences.

It shows how to transmit the last element from the observed source to create a new sequence:

In the list of installed applicationstake()AndtakeLast()Result After function:

Only once

An observed sequence is repeatedly transmitted when an error occurs or is designed to be repeatedly transmitted.distinct()AnddistinctUntilChanged()The function allows us to easily handle this repetitive problem.

Distinct

What if we want to process a specified value only once? We can use our sequencedistinct()Remove duplicate functions. Just liketakeLast()Same,distinct()Act on a complete sequence and get repeated filtering items. It needs to record each transmitted value. If you are processing a large number of sequences or big data, remember to pay attention to memory usage.

Demonstrate how to create a sequence with no duplicates on an observed source that emits 1 and 2:

To create a sequence in our example, we will use several methods we have learned so far:
*take(): It has a group of identifiable data items.
*repeat(): Create a large Recurring Sequence.

Then, we will applydistinct()Function to remove duplicates.

Note:

We use a program to implement a repeated sequence and then filter them out. This sounds incredible, but it is a good exercise to implement this example to use what we have learned so far.

Observable fullOfDuplicates = Observable.from(apps)    .take(3)    .repeat(3);

fullOfDuplicatesIn the variable, we repeat the first three installed applications three times: nine and many. Then, we usedistinct():

fullOfDuplicates.distinct()            .subscribe(new Observable() {                @Override                public void onCompleted() {                    mSwipeRefreshLayout.setRefreshing(false);                }                @Override                public void onError(Throwable e) {                    Toast.makeText(getActivity(), "Something went wrong!", Toast.LENGTH_SHORT).show();                    mSwipeRefreshLayout.setRefreshing(false);                }                @Override                public void onNext(AppInfo appInfo) {                    mAddedApps.add(appInfo);                     mAdapter.addApplication(mAddedApps.size() - 1,appInfo);                }            });}

Obviously, we get:

DistinctUntilsChanged

What should we do if we receive a notification when a new value is transmitted in an observability sequence? We assume that the temperature sensor we observe emits the indoor temperature per second:

21°https://github.com/yuxingxin/RxJava-Essentials-CN/raw/master.21°https://github.com/yuxingxin/RxJava-Essentials-CN/raw/master.21°https://github.com/yuxingxin/RxJava-Essentials-CN/raw/master.21°https://github.com/yuxingxin/RxJava-Essentials-CN/raw/master.22°https://github.com/yuxingxin/RxJava-Essentials-CN/raw/master.

Each time we get a new value, we update the temperature currently being displayed. Because of system resource protection, we do not want to update data every time the values are the same. We want to ignore repeated values and get notifications only when the temperature does change.ditinctUntilChanged()The filter function can do this. It can easily ignore all duplicates and only emit new values.

The following figure shows howdistinctUntilChanged()Function applications create a new sequence of non-repeated emission elements in an existing sequence.

First and last

Demonstrate how to create a sequence that only emits the first element from an observed source sequence.

first()Method andlast()The method is easy to understand. They only emit the first or last element from the Observable. Both can be passedFunc1As a parameter: a predicate that determines the first or last one we are interested in: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4NCjxwPs/CzbzVucq + wcs8Y29kZT5sYXN0KCk8L2NvZGU + Signature = "" src = "http://www.bkjia.com/uploads/allimg/160115/0413416019-8.png" title = "\"/>

Andfirst()Andlast()Similar variables include:firstOrDefault()AndlastOrDefault()These two functions are useful when the observed sequence is complete and no value is emitted. In this scenario, if the Observable does not emit any value, we can specify a default value.

Skip and SkipLast

Demonstrate how to useskip(2)Create a sequence of data after the first two elements instead of transmitting them.

skip()AndskipLast()Functions andtake()AndtakeLast()Correspondingly. They use integer N as parameters. In essence, they do not allow the Observable to emit the first N or the last N values. If we know that a sequence starts or ends with not many "controllable" elements, we can use it.

Correspond to the previous scenario: we create a new sequence that skips the remaining two elements from the source sequence.

ElementAt

What if we only want the fifth element that can be transmitted by the observed sequence?elementAt()The function only emits the nth element from a sequence and then completes.

What should we do if we want to find the fifth element but the observed sequence has only three elements available for transmitting? We can useelementAtOrDefault(). Demonstrate how to useelementAt(2)Select the third element from a sequence and create a new Observable that only emits the specified element.

Sampling

Let's go back to the temperature sensor. It emits the current indoor temperature every second. To be honest, we don't think the temperature will change so fast, so we can use a small launch interval. Addsample()We will create a new observability sequence, which will transmit the most recent value by the Observable at a specified interval:

Observable
  
    sensor = [...]sensor.sample(30,TimeUnit.SECONDS)    .subscribe(new Observable
   
    () {        @Override        public void onCompleted() {        }        @Override        public void onError(Throwable e) {        }        @Override        public void onNext(Integer currentTemperature) {            updateDisplay(currentTemperature)        }    });
   
  

In this example, the Observable will observe the temperature Observable and then emit the last temperature value every 30 seconds. Obviously,sample()All time units are supported: seconds, milliseconds, days, minutes, and so on.

It shows how to sample an Observable with a letter to be sent at an interval. The result of the Observable will emit the last group of data for each letter that has been sent:, 5.

If we want it to regularly launch the first element instead of the latest one, we can usethrottleFirst().

Timeout

Suppose we work in a time-sensitive environment, and our temperature sensor emits a temperature value every second. We want it to launch at least one task every two seconds. We can usetimeout()Function to listen to the source observability sequence, that is, if we do not get a value within the set interval, an error will be sent. We can think thattimeout()It is a time-limited copy of an Observable. If the Observable does not emit a value within the specified time interval, the original Observable it listens to will triggeronError()Function.

Subscription subscription = getCurrentTemperature()    .timeout(2,TimeUnit.SECONDS)    .subscribe(new Observable
  
   
    
     () {        @Override        public void onCompleted() {        }        @Override        public void onError(Throwable e) {            Log.d("RXJAVA","You should go check the sensor, dude");        }        @Override        public void onNext(Integer currentTemperature) {            updateDisplay(currentTemperature)        }    });
    
   
  

Andsample()Same,timeout()UseTimeUnitObject To specify the time interval.

As shown in, once the Observable exceeds the limit, it will triggeronError()Function: the last element is not transmitted because it arrives only after timeout.

Debounce

debounce()The function filters out the data transmitted by the Observable at an excessively high rate. If no data is released after a specified time interval, the function then transmits the last data.

Just likesample()Andtimeout()Functions are the same,debounce()UseTimeUnitThe specified time interval of the object.

Shows how often new data is sent from the Observable,debounce()The function enables an Internal timer. If no new data is sent during this interval, the new Observable emits the last data:

Summary

In this chapter, we learned how to filter an observed sequence. We can now usefilter(),skip(), Andsample()To create the desired Observable.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.