Android

Understanding Java 8 Stream and RxJava2 Observable in Android

In my last tutorial, I have described some of the superior features added in java version 8. In this tutorial, we will learn how RxJava-2 Observable is strongly following Java Stream. I would be recommended to check this post-Java 8 features to start using in android

Before learning Rx Observable in Android we need to understand Java Stream because Java is core programming to building an android app and the perspective of the concept is exactly same as Rx Observable.  Awesome Let’s start to understand Rx Observable but before first thing, we need to know what is Stream in Java?

“Everything is a stream.”

If we talk about Stream in common language it means a continuous flow of data or instructions, typically one having a constant or predictable rate or in another word transmit or receive (data, especially video and audio material) over the Internet as a steady, continuous flow. From the definition it clear that a continuous flow of liquid, air, or gas is called stream.

Yes, an exactly same meaning of Java Stream also. Let me define it in the technical term, A class that supports function style operation on a stream of elements like Filter, Map, sorted etc. Ohh sounds not understand right here Ok. But I am sure guaranteed that end of the tutorial you will able to get to know the thing clear.

Let me explain this with an example in the technical term what is Java Stream and Rx Observable that how we can use in general programming? Let’s say I have a list of devices and I want to iterate and print the list of elements by using Java Stream and Rx Observable.

Java Stream

List<String> versionList = Arrays.asList("Marshmallow", "Lolipop", "Kitkat", "Jelly Bean");
 versionList.stream()
 .forEach(s-> System.out.print(s));

Rx Observable

List<String> versionList = Arrays.asList("Marshmallow", "Lolipop", "Kitkat", "Jelly Bean");
Observable.fromIterable(versionList)
        .forEach(s-> Log.i("TAG",s)); // Android

If we look into above both programmings, it’s clear that concept is almost matching.

Now Let me take an another example which is used in daily programming which I am taking from my last post. Suppose I have a list of mobile devices of the different platform like android and ios of different -2 versions. In which some of the devices have defected and some are not.  But I am not sure which are not defect.

So basically I want those devices which have not defected and have platform android version 6.  So let’s check how we can use stream concept here to filter and map by using Rx Observable.  I explained in my the last post that how to identify the devices have not defected and android version 6? Here I need to use Predicate function of Java 8. I hoping you understand the Predicate meaning from the last post. But here I don’t use Java 8 stream. Now I want to use Predicate of the RxJava2 feature.

public static Predicate<MobileDevices> isAndroidVersion6() {
        return p -> p.getVersion() == 6 && p.getPlatform().equalsIgnoreCase("Android") && ! p.isDefect();
    }

Now I need to filter devices with this predicated devices from a list of devices by using  RxJava.

public static List<MobileDevices> filterMobileDevices (List<MobileDevices> mobileDevices, Predicate<MobileDevices> predicate) {
        List<MobileDevices> mobileDevicesList = new ArrayList<>();
        Observable.fromIterable(mobileDevices).filter(predicate ).forEach(new Consumer<MobileDevices>() {
            @Override
            public void accept(@NonNull MobileDevices mobileDevices) throws Exception {
                 mobileDevicesList.add(mobileDevices);
            }
        });
        return mobileDevicesList;
    }

Now I want to call this method and iterate to check that filtered list is exactly same as  I was expecting.

        List<TestRxJava.MobileDevices> mobileDevicesList = TestRxJava.generateDevices();
        List<TestRxJava.MobileDevices> mobileDevicesListAndroid = TestRxJava.getNotDefectedAndroidVersion6Devices(mobileDevicesList);
        Observable.fromIterable(mobileDevicesListAndroid).forEach(new Consumer<TestRxJava.MobileDevices>() {
            @Override
            public void accept(@NonNull TestRxJava.MobileDevices mobileDevices) throws Exception {

                String deviceName = mobileDevices.getDeviceName();
                Log.v("Android", deviceName);
            }
        });

Here is the result:

Android: Samsung
Android: LG
Android: Micromax

Great 🙂 Awesome Rx Java and Rx Android. Great Thanks to Java 8 Stream.

Here is all code one place.

import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Predicate;


/**
 * Created by sunil on 30-04-2017.
 */
public class TestRxJava {

    private static List<MobileDevices> mobileDevicesList;

    public static List<MobileDevices> generateDevices(){
        mobileDevicesList = new ArrayList<>();
        mobileDevicesList.clear();
        MobileDevices mobileDevice1 = new MobileDevices("Google Pixel", "Android", 6, true);
        MobileDevices mobileDevice2 = new MobileDevices("Samsung", "Android", 6, false);
        MobileDevices mobileDevice3 = new MobileDevices("Motorola", "Android", 5, false);
        MobileDevices mobileDevice4 = new MobileDevices("IPhone", "ios", 5, false);
        MobileDevices mobileDevice5 = new MobileDevices("LG", "Android", 6, false);
        MobileDevices mobileDevice6 = new MobileDevices("Lenevo", "Android", 6, true);
        MobileDevices mobileDevice7 = new MobileDevices("Micromax", "Android", 6, false);
        MobileDevices mobileDevice8 = new MobileDevices("Iphone", "ios", 6, false);
        mobileDevicesList.add(mobileDevice1);
        mobileDevicesList.add(mobileDevice2);
        mobileDevicesList.add(mobileDevice3);
        mobileDevicesList.add(mobileDevice4);
        mobileDevicesList.add(mobileDevice5);
        mobileDevicesList.add(mobileDevice6);
        mobileDevicesList.add(mobileDevice7);
        mobileDevicesList.add(mobileDevice8);
        return mobileDevicesList;
    }

     public  static List<MobileDevices> getNotDefectedAndroidVersion6Devices(List<MobileDevices> mobileDevices){
        Predicate<MobileDevices> mobileDevicesPredicate = isAndroidVersion6();
        return  filterMobileDevices(mobileDevices, mobileDevicesPredicate);
    }

    public static Predicate<MobileDevices> isAndroidVersion6() {
        return p -> p.getVersion() == 6 && p.getPlatform().equalsIgnoreCase("Android") && ! p.isDefect();
    }

    public static List<MobileDevices> filterMobileDevices (List<MobileDevices> mobileDevices, Predicate<MobileDevices> predicate) {
        List<MobileDevices> mobileDevicesList = new ArrayList<>();
        Observable.fromIterable(mobileDevices).filter(predicate ).forEach(new Consumer<MobileDevices>() {
            @Override
            public void accept(@NonNull MobileDevices mobileDevices) throws Exception {
                 mobileDevicesList.add(mobileDevices);
            }
        });
        return mobileDevicesList;
    }

    public static class MobileDevices{

       private String deviceName;
       private String platform;
       private int version;
       private boolean isDefect;

        public MobileDevices(String deviceName, String platform, int version, boolean isDefect) {
            this.deviceName = deviceName;
            this.platform = platform;
            this.version = version;
            this.isDefect = isDefect;
        }

        public String getDeviceName() {
            return deviceName;
        }

        public String getPlatform() {
            return platform;
        }

        public int getVersion() {
            return version;
        }

        public boolean isDefect() {
            return isDefect;
        }
    }
}

and calling this function in the Main function.

List<TestRxJava.MobileDevices> mobileDevicesList = TestRxJava.generateDevices();
        List<TestRxJava.MobileDevices> mobileDevicesListAndroid = TestRxJava.getNotDefectedAndroidVersion6Devices(mobileDevicesList);
        Observable.fromIterable(mobileDevicesListAndroid).forEach(new Consumer<TestRxJava.MobileDevices>() {
            @Override
            public void accept(@NonNull TestRxJava.MobileDevices mobileDevices) throws Exception {

                String deviceName = mobileDevices.getDeviceName();
                Log.v("Android", deviceName);
            }
        });

Awesome. Loved it (Rx Observable). I would say everyone should start using Stream concept.

Please do subscribe to the next post. Enjoy this post  🙂

0 0 votes
Article Rating

Recent Posts

Hide your production API key or any sensitive data in Android

Hi everyone, In this article, we are going to learn how to hide the production… Read More

2 years ago

How to handle the localisation or multi language support in android with examples?

Hello everyone, Today in this article, we are going to learn about localisation to support… Read More

2 years ago

How to convert any callback to Coroutines and use them in Kotlin Android?

Hello everyone, In this article, we are going to learn something to handle the callback… Read More

2 years ago

Request Permission Launcher with Kotlin in Android

In this article, we are learning about the run time permissions for request permission launchers.… Read More

2 years ago

Implement the SMS User Consent API and SMS Retriever API in Android

Hello everyone. In my last tutorial, we learned about the Jetpack Compose introduction and about applying the… Read More

3 years ago

Jetpack Compose Coroutine flow with LiveData/ViewModel in Android

Hello everyone, In this article, we are going to learn about the Jetpack Compose with… Read More

3 years ago