In the previous two articles, we introduced some basic concepts of rxjava and the simplest usage of rxjava. From this chapter, we start talking about the operators in Rxjava the operators in Operators,rxjava are divided into three main categories:
- Conversion class operator (
map
flatMap
concatMap
flatMapIterable
switchMap
scan
groupBy
...) ;
- Filter Class Operators (
fileter
take
takeLast
takeUntil
distinct
distinctUntilChanged
skip
skipLast
...) ;
- Grouping class operators (...
merge
zip
join
combineLatest
and/when/then
switch
startSwitch
).
In this chapter we mainly talk about conversion class operators. All of these operators are used for an observable sequence, then transform the values it emits, and finally return them in a new form. The concept is really not good understanding, the following we have a practical example of the introduction.
Map
map()
The function takes a parameter of type FUNC1 (like this map(Func1<? super T, ? extends R> func)
), then the FUNC1 is applied to each value emitted by the observable, and the emitted is converted only to the value we expect. This bullshit definition, I'm sure you don't understand, let's take a look at the official schematics:
Mapoperator
Suppose we need to replace a set of numbers with strings, which we can do with a map:
observable.just (1, 2, 3, 4, 5). Map (new Func1<integer, string> () { @Override public String call return "This is" + I;}). Subscribe (new action1<string> () { @Override public void call< Span class= "Hljs-params" > (String s) {System.out.println (s);}});
The two parameters in the Func1 constructor are the current type of the observable emission value and the map-converted type, the current type of the emitted value in the above example is integer and the converted type is string.
FlatMap
flatMap()
Functions are also converted, but they do not work the same. Flatmap not open good understanding, we look directly at the example (our company is a real estate platform, then I take the house example): Suppose we have a group Community[] communites
of cells, now we want to output the name of each cell; we can do this:
Observable.from(communities) .map(new Func1<Community, String>() { @Override public String call(Community community) { return community.name; } }) .subscribe(new Action1<String>() { @Override public void call(String name) { System.out.println("Community name : " + name); } });
Now we have a change in demand and need to print out the prices of all the houses under each cell. So I can achieve this:
Community[] communities = {};Observable.from(communities) .subscribe(new Action1<Community>() { @Override public void call(Community community) { for (House house : community.houses) { System.out.println("House price : " + house.price); } } });
If I don't want to use a for loop in subscriber, I want to pass in a single House object directly in the Subscriber (which is important for code reuse)? Using map () is obviously not possible, because map () is a one-to-one conversion, and my current requirement is a one-to-many conversion. Then we can use Flatmap () to convert a community into multiple house.
observable.from (communities). FlatMap (new Func1<community, observable @Override public observablecallreturn observable.from (community.houses);}) . Subscribe (new action1 @Override public void call< Span class= "Hljs-params" (House House) {System.out.println ( "house price:" + House.price);} });
As you can see from the previous example, FlatMap () and map () are converted to another object after conversion of the parameters passed in. However, unlike map (), the observable object is returned in FlatMap (), and the observable object is not sent directly to the Subscriber callback method.
The principle of flatMap () is this:
- Replace the incoming event object with a observable object;
- This is not to send this observable directly, but to activate this observable to let it start sending events by itself;
- Every event that is created by observable is sent to the same observable, which observable is responsible for unifying these events to the Subscriber callback method.
In these three steps, the event was split into level two and distributed through a unified path after the initial object was "flattened" by a newly created set of observable. And this "flattening" is flatmap () the so-called flat.
Finally, let's take a look at Flatmap's schematic diagram:
Flatmapoperatorconcatmap
concatMap()
Solves flatMap()
the crossover problem, it can put the value of the emission together, just like this:
Concatmapoperatorflatmapiterable
flatMapIterable()
and flatMap()
almost the same, the difference is that flatMapIterable()
it transforms multiple observable using iterable as the source data.
Flatmapiterableoperator
Observable.from(communities) .flatMapIterable(new Func1<Community, Iterable<House>>() { @Override public Iterable<House> call(Community community) { return community.houses; } }) .subscribe(new Action1<House>() { @Override public void call(House house) { } });
Switchmap
switchMap()
And flatMap()
much like, except for one thing: whenever Observable
a source launches a new data item (Observable), it cancels the subscription and stops monitoring the previous data item Observable
, and starts to monitor the current launch.
Switchmapoperatorscan
scan()
A function is applied to the data of a sequence and the result of the function is emitted as the first parameter used when the next data is applied to the qualifying function.
Scanoperator
Let's look at a simple example:
observable.just (1, 2, 3, 4, 5). Scan (new Func2<integer, Integer, integer> () { @Override public Integer callreturn Integer + Integer2;}}). Subscribe (new action1<integer> () { @Override public void call< Span class= "Hljs-params" (Integer integer) {System.out.print (integer+ "");}});
The output is: 1 3 6 10 15
GroupBy
groupBy()
The data emitted by the original observable is split into small observable by key, and the small observable emit the data they contain, similar to the GroupBy in SQL. In practice, we need to provide a rule that generates a key (that is, the call method in Func1), and all keys with the same data are included in the same small observable. In addition, we can provide a function to convert the data, a bit similar to the integration of Flatmap.
Groupbyoperator
Simple text description and picture interpretation may be difficult to understand, let's look at an example: Suppose I now have a group of listings List<House> houses
, each house belongs to a certain community, now we need to classify the listing according to the cell name, then the listing information output.
ListNew Arraylist<> (); Houses.add (New House ("Cofco/Seaview","One of the new large flat floor of Cofco Seaview!" Total Price 4500W ")); Houses.add (New House ( "Chuk Yuen San Tsuen", "full five unique, prime location"); Houses.add ( new House ( "Cofco/Seaview One", "adjacent to Tomson")); Houses.add (new House ( "Chuk Yuen San Tsuen", new House (" Cofco/Seaview One ", " North-south permeability, deluxe five-room)); observable<groupedobservable<string, house>> groupbycommunitynameobservable = Observable.from (houses). GroupBy (new Func1<House, String> () { @Override public String call (House house) {return House.communityname; } });
By the above code we create a new observable: groupByCommunityNameObservable
It will send a sequence with a (that is, the GroupedObservable
type of data item being sent is groupedobservable). GroupedObservable
is a special Observable
, it is based on a grouped key, in this case the key is the cell name. Now we need to output the categorized listings in turn:
Observable.concat(groupByCommunityNameObservable) .subscribe(new Action1<House>() { @Override public void call(House house) { System.out.println("小区:"+house.communityName+"; 房源描述:"+house.desc); } });
Execution Result:
小区:中粮·海景壹号; 房源描述:中粮海景壹号新出大平层!总价4500W起小区:中粮·海景壹号; 房源描述:毗邻汤臣一品小区:中粮·海景壹号; 房源描述:南北通透,豪华五房小区:竹园新村; 房源描述:满五唯一,黄金地段小区:竹园新村; 房源描述:顶层户型,两室一厅
The operator of the conversion class first introduced to this, the following will continue to introduce the combination, filter class operators and source analysis, please look forward to!
Links: https://www.jianshu.com/p/5970280703b9
Rxjava Series 3 (conversion operator)