Skip to content

6. The functional interfaces of the RxJava library

The Observable class forms the basis of the RxJava asynchronous library. It shares many similarities with the Stream class we just discussed. Like Stream, it offers a large number of methods—several dozen. And like Stream, these methods accept instances of functional interfaces as parameters. We’ll start by introducing the most common ones: [Action] and [Function].

6.1. Example-01: The [Action0] functional interface

  

The [Action0] interface is as follows:

  • The [Action0] interface has a single method, `call`, with the signature [2]: `void call()`. It derives from the [Action] interface [1, 3]. The [Action] interface has no methods. This type of interface is called a marker interface [4]. They are mainly used to write: if(c instanceOf(Action)) {...}. The [Action] interface itself derives from the marker interface [Function] [4-6];
 

We will illustrate the [Action0] interface with the following code (Example01):


package dvp.rxjava.lamdbas;

import rx.functions.Action0;

public class Example01 {
  public static void main(String[] args) {
    // Action0
    Action0 a01 = new Action0() {
      @Override
      public void call() {
        System.out.println("anonymous a01.call");
      }
    };
    Action0 a02 = () -> System.out.println("lambda ao2.call");
    // output
    a01.call();
    a02.call();
  }
}
  • lines 8–13: implementation of the [Action0] interface using an anonymous class;
  • lines 8–13: implementation of the [Action0] interface using a lambda;

The results are as follows:

anonymous a01.call
lambda ao2.call

6.2. Example-02, 03: the functional interface [Actioni]

  

The interface [Action1] is as follows:

 

We will illustrate this with the following code (Example 02):


package dvp.rxjava.lamdbas;

import rx.functions.Action1;

public class Example02 {
  public static void main(String[] args) {
    // Action1
    Action1<Integer> a10 = new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
        System.out.printf("anonymous a10.call (%s)%n", integer);
      }
    };
    Action1<Double> a11 = (d -> System.out.printf("lambda a11.call (%s)%n", d));

    // executions
    a10.call(20);
    a11.call(17.4);
  }
}

which gives the following result:

anonymous a10.call (20)
lambda a11.call (17.4)

In general, [Actioni] (0 <= i <= 9) is a functional interface with a single method of the following signature: void call(T1 t1, T2 t2, ..., Ti ti). Here is an example for [Action2] (Example03):


package dvp.rxjava.lamdbas;

import rx.functions.Action2;

public class Example03 {
  public static void main(String[] args) {
    // Action2
    Action2<Integer, Double> a20 = new Action2<Integer, Double>() {
      @Override
      public void call(Integer integer, Double aDouble) {
        System.out.printf("anonymous a20.call(%s,%s)%n", integer, aDouble);
      }
    };
    Action2<Integer, Double> a21 = (i, d) -> System.out.printf("lambda a21.call(%s,%s)%n", i, d);
    // executions
    a20.call(10, 11.3);
    a21.call(5, 5.6);
  }
}

The result is as follows:

anonymous a20.call(10,11.3)
lambda a21.call(5,5.6)

6.3. Example-04, 05: the functional interface [Funci]

  

The [Func0] interface is as follows:

 

This time, the [call] method of the interface returns a result of type R.

We will illustrate the interface with the following code:


package dvp.rxjava.lamdbas;

import rx.functions.Func0;

public class Example04 {
  public static void main(String[] args) {
    // Function0
    Func0<String> f00 = new Func0<String>() {
      @Override
      public String call() {
        return "anonymous f00.call";
      }
    };
    Func0<String> f01 = () -> "lambda f01.call";
    // executions
    System.out.println(f00.call());
    System.out.println(f01.call());
  }
}

which produces the following results:


anonymous a20.call(10,11.3)
lambda a21.call(5,5.6)

In general, [Funci] (0<=i<=9) is a functional interface with a single method signature: R call(T1 t1, T2 t2, ..., Ti ti). Here is an example for [Func2] (Example05):


package dvp.rxjava.lamdbas;

import rx.functions.Func2;

public class Example05 {
  public static void main(String[] args) {
    // Func2
    Func2<Integer, Double, String> f20 = new Func2<Integer, Double, String>() {
      @Override
      public String call(Integer integer, Double aDouble) {
        return String.format("anonymous f20.call(%s,%s)", integer, aDouble);
      }
    };
    Func2<Integer, Double, String> f21 = (i, d) -> String.format("anonymous f21.call(%s,%s)", i, d);
    // output
    System.out.println(f20.call(10, 10.2));
    System.out.println(f21.call(100, 100.3));
  }
}

which gives the following results:

anonymous f20.call(10, 10.2)
anonymous f21.call(100,100.3)