Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Arrow up icon
GO TO TOP
Learning RxJava

You're reading from   Learning RxJava Build concurrent applications using reactive programming with the latest features of RxJava 3

Arrow left icon
Product type Paperback
Published in Feb 2020
Publisher Packt
ISBN-13 9781789950151
Length 412 pages
Edition 2nd Edition
Languages
Tools
Arrow right icon
Authors (2):
Arrow left icon
Nick Samoylov Nick Samoylov
Author Profile Icon Nick Samoylov
Nick Samoylov
Thomas Nield Thomas Nield
Author Profile Icon Thomas Nield
Thomas Nield
Arrow right icon
View More author details
Toc

Table of Contents (22) Chapters Close

Preface 1. Section 1: Foundations of Reactive Programming in Java
2. Thinking Reactively FREE CHAPTER 3. Observable and Observer 4. Basic Operators 5. Section 2: Reactive Operators
6. Combining Observables 7. Multicasting, Replaying, and Caching 8. Concurrency and Parallelization 9. Switching, Throttling, Windowing, and Buffering 10. Flowable and Backpressure 11. Transformers and Custom Operators 12. Section 3: Integration of RxJava applications
13. Testing and Debugging 14. RxJava on Android 15. Using RxJava for Kotlin 16. Other Books You May Enjoy Appendix A: Introducing Lambda Expressions 1. Appendix B: Functional Types 2. Appendix C: Mixing Object-Oriented and Reactive Programming 3. Appendix D: Materializing and Dematerializing 4. Appendix E: Understanding Schedulers

A brief exposure to RxJava

Before we dive deep into the reactive world of RxJava, here is a quick immersion to get your feet wet first. In ReactiveX, the core type you will work with is the Observable class. We will be learning more about the Observable class throughout the rest of this book. But essentially, an Observable pushes things. A given Observable<T> pushes things of type T through a series of operators until it arrives at an Observer object that consumes the items.

For instance, create a new Ch1_1.java file in your project and put in the following code:

import io.reactivex.rxjava3.core.Observable;
public class Ch1_1 {
public static void main(String[] args) {
Observable<String> myStrings =
Observable.just("Alpha", "Beta", "Gamma");
}
}

In our main() method, we have an Observable<String> that will push three string objects. An Observable can push data or events from virtually any source, whether it is a database query or live Twitter feeds. In this case, we are quickly creating an Observable using Observable.just(), which will emit a fixed set of items.

In RxJava 1.x, the types are contained in the rx package. In RxJava 2.x, most types you will use are contained in the io.reactivex package. In RxJava 3.0, most types you will use are contained in the io.reactivex.rxjava3 package.

However, running this main() method is not going to do anything other than declare Observable<String>. To make this Observable actually push (or emit) these three strings, we need an Observer object to subscribe to it and receive the items. We can quickly create and connect an Observer object by passing a lambda expression that specifies what to do with each value it receives:

import io.reactivex.rxjava3.core.Observable;
public class Ch1_1 {
public static void main(String[] args) {
Observable<String> myStrings =
Observable.just("Alpha", "Beta", "Gamma");
myStrings.subscribe(s -> System.out.println(s));
}
}

When we run this code, we should get the following output:

Alpha 
Beta
Gamma

What happened here is that our Observable<String> pushed each string object one at a time to our Observer object, which we shorthanded using the s -> System.out.println(s) lambda expression. We passed each string through the (arbitrarily named) s parameter and instructed it to print each one. Lambda expressions are essentially mini-functions that allow us to quickly pass instructions on what action to take with each incoming item. Everything to the left of the arrow (->) are arguments (which, in this case, is a string we named s), and everything to the right is the action (which is System.out.println(s)).

If you are unfamiliar with lambda expressions, turn to Appendix A, Introducing Lambda Expressions, to learn more about how they work. If you want to invest extra time in understanding lambda expressions, I highly recommend that you read at least the first few chapters of Java 8 Lambdas (O'Reilly) (http://shop.oreilly.com/product/0636920030713.do), by Richard Warburton. Lambda expressions are a critical topic in modern programming and have become especially relevant to Java developers since their adoption in Java 8. We will be using lambdas constantly in this book, so definitely take some time to get comfortable with them.

We can also use several operators in the pipeline between Observable and Observer to transform each pushed item or manipulate it in some way. Each such operator applies the transformation and returns a new Observable that emits the transformed item. For example, we can use map() to turn each string emission into its length(), and each length integer will then be pushed to Observer, as shown in the following code snippet:

import io.reactivex.rxjava3.core.Observable;
public class Ch1_2 {
public static void main(String[] args) {
Observable<String> myStrings =
Observable.just("Alpha", "Beta", "Gamma");
myStrings.map(s -> s.length())
.subscribe(s -> System.out.println(s));
}
}

When we run this code, we should get the following output:

5
4
5

If you have used Java 8 streams or Kotlin sequences, you might be wondering how Observable is any different. The key difference is that Observable pushes the items, while the streams and sequences pull the items. This may seem subtle, but the impact of a push-based iteration is far more powerful than a pull-based one. As we saw earlier, you can push not only data but also events. For instance, Observable.interval() will push a consecutive Long at each specified time interval, as shown in the following code snippet. This Long emission is not only data but also an event! Let's take a look:

import io.reactivex.rxjava3.core.Observable;
import java.util.concurrent.TimeUnit;
public class Ch1_3 {
public static void main(String[] args) {
Observable<Long> secondIntervals =
Observable.interval(1, TimeUnit.SECONDS);
secondIntervals.subscribe(s -> System.out.println(s));
/* Hold main thread for 5 seconds
so Observable above has chance to fire */
sleep(5000);
}
public static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

When we run this code, we should get the following output:

0 
1
2
3
4

Notice that a consecutive emission fires every second. This application runs for about 5 seconds before it quits, and you likely see emissions 0 to 4 fired, each separated by a just a second-long gap. This simple idea that data is a series of events over time unlocks new possibilities in programming.

As a side note, we will get more into concurrency later, but we had to create a sleep() method because this Observable fires emissions on a computation thread when the Observable is subscribed to. The main thread used to launch our application is not going to wait on this Observable since it fires on a computation thread, not the main thread. Therefore, we use sleep() to pause the main thread for 5,000 milliseconds and then allow it to reach the end of the main() method (which will cause the application to terminate). This gives Observable.interval() a chance to fire for the 5-second window before the application quits.

Throughout this book, we will uncover many mysteries about Observable and the powerful abstractions it takes care of for us. If you've conceptually understood what's been going on here so far, congrats! You are already becoming familiar with how reactive code works. To emphasize again, emissions are pushed one at a time, all the way to Observer. Emissions represent both data and an event, which can be emitted over time. Of course, beyond map(), there are hundreds of operators in RxJava, and we will learn about the key ones in this book. Learning which operators to use for a situation and how to combine them is the key to mastering RxJava. In the next chapter, we will cover Observable and Observer much more comprehensively. We will also demystify how events and data are being represented in Observable a bit more.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
Learning RxJava
You have been reading a chapter from
Learning RxJava - Second Edition
Published in: Feb 2020
Publisher: Packt
ISBN-13: 9781789950151
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Modal Close icon
Modal Close icon