Turn: Easy to Rxjava (ii: operator)

Source: Internet
Author: User

Original address: Http://blog.csdn.net/lzyzsd/article/details/44094895#comments

In the first blog, I introduced some of the basics of Rxjava and also introduced the map () operator. Of course, if you do not intend to use the Rxjava I am not surprised, after all, the touch of this point. After reading this blog, I am sure you want to immediately use Rxjava in your project, this blog will introduce many Rxjava in the operator, Rxjava's power comes from its defined operators.

First, let's look at an example:

Preparatory work

Suppose I have such a method:
This method returns a list of URLs for a website based on the input string (AHA, search engine)

[Java]View PlainCopy
    1. observable<list<string>> query (String text);

Now I want to build a robust system that can query strings and display results. Based on the content of the previous blog, we may write the following code:

[Java]View PlainCopy
    1. Query ("Hello, world!")
    2. . Subscribe (URLs, {
    3. For (String url:urls) {
    4. System.out.println (URL);
    5. }
    6. });

This code is, of course, intolerable, because the code above makes us lose the ability to change the flow of data. Once we want to change each URL, we can only do it in subscriber. We did not use such a cool map () operator!!!

Of course, I can use the map operator, map input is the list of URLs, processing time or for each traversal, just as the egg hurts.

Fortunately, there is also the Observable.from () method, which receives a collection as input, and then outputs one element at a time to the Subscriber:

[Java]View PlainCopy
    1. Observable.from ("Url1", "Url2", "Url3")
    2. . Subscribe (URL, System.out.println (URL));

Let's use this method to the scene just now:

[Java]View PlainCopy
    1. Query ("Hello, world!")
    2. . Subscribe (URLs, {
    3. Observable.from (URLs)
    4. . Subscribe (URL, System.out.println (URL));
    5. });

Although the For Each loop is removed, the code still looks messy. Multiple nested subscription not only look ugly, difficult to modify, but more serious, it destroys some of the Rxjava features that we have not talked about yet.

Improved

The savior came, and he was Flatmap ().
Observable.flatmap () receives a Observable output as input and outputs another Observable. Look directly at the code:

[Java]View PlainCopy
  1. Query ("Hello, world!")
  2. . FLATMAP (new Func1<list<string>, observable<string>> () {
  3. @Override
  4. Public observable<string> Call (list<string> URLs) {
  5. return Observable.from (URLs);
  6. }
  7. })
  8. . Subscribe (URL, System.out.println (URL));

Here I've posted the entire function code to make it easy for you to understand what's going on, and using lambda can greatly simplify the length of the code:

[Java]View PlainCopy
    1. Query ("Hello, world!")
    2. . FLATMAP (URLs-Observable.from)
    3. . Subscribe (URL, System.out.println (URL));

FlatMap () Does it look strange? Why does it have to go back to another observable? The key to understanding Flatmap is that the new observable that flatmap output is what we want to receive in subscriber. Now subscriber no longer receives LIST<STRING> instead, it receives columns of a single string, just like the output of Observable.from ().

This is part of my first learning Rxjava when the most difficult to understand the part, once I suddenly understand, rxjava a lot of doubts also solved.

can also be better

FlatMap () is not much better, it can return any observable object it wants to return.
For example, the following method:

[Java]View PlainCopy
    1. Returns the title of the Web site and returns null if 404 is returned
    2. Observable<string> GetTitle (String URL);

And then the previous example, now I don't want to print the URL, but to print the title of each Web site I received. Here's the problem, my method can only pass in one URL at a time, and the return value is not a string, but an Observabl object that outputs a string. Using Flatmap () can be a simple solution to this problem.

[Java]View PlainCopy
  1. Query ("Hello, world!")
  2. . FLATMAP (URLs-Observable.from)
  3. . FLATMAP (new func1<string, observable<string>> () {
  4. @Override
  5. Public observable<string> call (String URL) {
  6. return GetTitle (URL);
  7. }
  8. })
  9. . Subscribe (title), System.out.println (title);

Using lambda:

[Java]View PlainCopy
    1. Query ("Hello, world!")
    2. . FLATMAP (URLs-Observable.from)
    3. . FlatMap (URL, getTitle (URL))
    4. . Subscribe (title), System.out.println (title);

Does it feel weird? I was able to combine multiple independent methods of returning observable objects! That's awesome!
More than that, I've also combined the calls of two APIs into a chain call. We can link any number of API calls together. You should all know that synchronizing all of the API calls and then combining the callback results of all the API calls into the data that needs to be presented is a pain in the back of the egg. Here we have successfully avoided callback hell (multiple layers of nested callbacks, which makes the code difficult to read and maintain). Now all the logic is packaged into this simple, responsive invocation.

Wide range of operator characters

So far, we've touched two operators, and there are more operators in Rxjava, so how do we use other operators to improve our code?
GetTitle () returns null if the URL does not exist. We do not want to output "null", so we can filter out null values from the returned title list!

[Java]View PlainCopy
    1. Query ("Hello, world!")
    2. . FLATMAP (URLs-Observable.from)
    3. . FlatMap (URL, getTitle (URL))
    4. . Filter (title-Title! = null)
    5. . Subscribe (title), System.out.println (title);

The filter () outputs the same elements as the input and filters out those that do not meet the check criteria.

If we want only a maximum of 5 results:

[Java]View PlainCopy
    1. Query ("Hello, world!")
    2. . FLATMAP (URLs-Observable.from)
    3. . FlatMap (URL, getTitle (URL))
    4. . Filter (title-Title! = null)
    5. . Take (5)
    6. . Subscribe (title), System.out.println (title);

Take () outputs a maximum of a specified number of results.

If we want to save each title to disk before printing:

[Java]View PlainCopy
    1. query ( "hello, world!")   
    2.     .flatmap (Urls -> observable.from (URLs))    
    3.     .flatmap (url -> gettitle (URL))   
    4.     .filter (title -> title != null)   
    5.     .take (5)   
    6.     .doonnext (Title -> savetitle (title))   
    7.     .subscribe (TITLE&NBSP;->&NBSP;SYSTEM.OUT.PRINTLN (title));  

Doonnext () allows us to do some extra things before each output of an element, such as the save title here.

See how easy it is to manipulate the data flow here. You can add as many actions as you have and don't mess up your code.

The Rxjava contains a large number of operators. The number of operators is a bit scary, but it's worth looking at, so you can see which operators are available. It may take some time to understand these operators, but once you understand them, you are fully in control of the power of Rxjava.

You can even write custom operators! This blog is not intended to be a custom operator, if you want to, clear your own Google bar.

How do you feel?

Well, you're a skeptic, and it's hard to convince, so why do you care about these operators?

Because the operator allows you to do anything with the data flow.

Complex logic can be accomplished by linked a series of operations together. The code is decomposed into a series of fragments that can be combined. This is the charm of responsive function programming. The more you use, the more you will change your programming thinking.

In addition, Rxjava makes it easier for us to process data. In the last example, we called two APIs, processed the data returned by the API, and then saved it to disk. But our subscriber don't know that, it just thinks they're receiving a observable<string> object. Good encapsulation also brings the convenience of coding!

In the third part, I'll cover some of the other cool features of Rxjava, such as error handling and concurrency, which are not directly used to manipulate the data.

Turn: Easy to Rxjava (ii: operator)

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.