Usage and example explanation of rxjava library operator of Java
The operator is to solve the problem of transformation of observable objects. The operator is used to modify the events sent by observable between observable and the final subscriber. Rxjava provides many useful operators. For example, the map operator is used to convert one event into another.
Using lambda can be simplified to
Isn't it cool? The map () operator is used to transform observable objects. The map operator returns an observable object, which enables chain calls. The map operator is used multiple times on an observable object, and finally the most concise data is passed to the subscriber object.
The more interesting thing about the map operator is that it does not have to return the type returned by the observable object. You can use the map operator to return an observable object that emits a new data type. For example, in the above example, the subscriber does not care about the returned string, but wants the hash value of the string
Isn't it interesting? Our initial observable returns a string, but the final subscriber receives an integer. Of course, using lambda can further simplify the code:
As mentioned earlier, the fewer things the subscriber does, the better. Let's add a map operator
Not satisfied? Do you think our example is too simple to convince you? You need to understand the following two points: 1 Observable and subscriber can do anything. Observable can be a database query, and subscriber is used to display query results; Observable can be a click event on the screen, and the subscriber is used to respond to the click event; Observable can be a network request, and the subscriber is used to display the request result. 2. Observable and subscriber are independent of the intermediate transformation process. Any number of maps can be increased or decreased between observable and subscriber. The whole system is highly composable, and operating data is a very simple process.
Example 1 Preparation: suppose I have such a method: this method returns a list of URLs of a website (aha, search engine) according to the input string
Now I want to build a robust system that can query strings and display results. According to the content of the previous blog, we may write the following code:
This kind of code is certainly intolerable, because the above code makes us lose the ability to change the data flow. Once we want to change each URL, we can only do it in subscriber. We didn't use such a cool map () operator!!!
Of course, I can use the map operator. The input of the map is the URLs list. When processing, it still needs to be traversed by for each. It's also very painful.
Fortunately, there is observable The from () method receives a collection as input, and then outputs one element at a time to the subscriber:
Let's apply this method to the scene just now:
Although the for each loop is removed, the code still looks messy. Multiple nested subscriptions not only look ugly and difficult to modify, but also destroy some rxjava features we haven't talked about yet.
2. Here comes the Savior of improvement. He is flatmap (). Observable. Flatmap () receives the output of one observable as input and outputs another observable at the same time. Look directly at the code:
Here I post the whole function code to make it easier for you to understand what happened. Using lambda can greatly simplify the code length:
Does flatmap () look strange? Why does it return another observable? The key to understanding flatmap is that the new observable output from flatmap is exactly what we want to receive in subscriber. Now, instead of receiving list < string >, the subscriber receives some single string columns, like observable The output of from () is the same.
This part is also the most difficult part for me to understand when I first learned rxjava. Once I suddenly understand it, many questions about rxjava will be solved together.
3. It's better. Flatmap () can't be better. It can return any observable object it wants to return. For example, the following methods:
Following the previous example, now I don't want to print the URL, but the title of each website I receive. The problem is that my method can only pass in one URL at a time, and the return value is not a string, but an observable object that outputs a string. Using flatmap () can simply solve this problem.
4. Use lambda:
Does it feel incredible? I can combine multiple independent methods that return observable objects! Awesome! More than that, I also combined the calls of the two APIs into a chain call. We can link any number of API calls. Everyone should know how painful it is to synchronize all API calls and then combine the callback results of all API calls into the data to be displayed. Here, we have successfully avoided the callback shell (multi-layer nested callback, which makes the code difficult to read and maintain). Now all logic is packaged into this simple responsive call.
5. Rich operators so far, we have contacted two operators. There are more operators in rxjava. How can we use other operators to improve our code? Gettitle() returns NULL if the URL does not exist. We don't want to output "null", so we can filter out the null value from the returned title list!
Filter () outputs the same elements as the input, and filters out those that do not meet the inspection conditions.
If we only want up to 5 Results:
Take() outputs up to the specified number of results.
If we want to save each title to disk before printing:
Doonnext () allows us to do something extra before outputting one element at a time, such as the save title here.
See how easy it is to manipulate the data flow here. You can add as many operations as you want without messing up your code.
Rxjava contains a large number of operators. The number of operators is a bit scary, but it's worth looking at one by one so that you can know which operators can be used. It may take some time to understand these operators, but once you understand them, you will fully grasp the power of rxjava.
You can even write custom operators! This blog is not going to customize operators. If you want, just Google yourself.
How do you feel? Well, you're a skeptic and hard to convince, so why do you care about these operators?
Because operators allow you to do anything with the data flow.
Complex logic can be accomplished by linking a series of operators. The code is broken down into a series of fragments that can be combined. This is the charm of responsive functional programming. The more you use, the more you will change your programming thinking.
In addition, rxjava also makes it easier for us to process data. In the last example, we call two APIs, process the data returned by the API, and then save it to disk. But our subscriber doesn't know this. It just thinks it is receiving an observable < string > object. Good encapsulation also brings the convenience of coding!
In the third part, I will introduce some other cool features of rxjava, such as error handling and concurrency, which are not directly used to process data.