Skip to content

6. Функціональні інтерфейси бібліотеки RxJava

Клас Observable є основою асинхронної бібліотеки RxJava. Він має багато схожостей із класом Stream, який ми щойно розглянули. Як і той, він містить дуже багато методів — кілька десятків. І, як і він, ці методи приймають як параметри екземпляри функціональних інтерфейсів. Почнемо з огляду найпоширеніших із них: [Actioni] та [Funci].

6.1. Приклад-01: функціональний інтерфейс [Action0]

  

Інтерфейс [Action0] виглядає так:

  • Інтерфейс [Action0] має єдиний метод call із сигнатурою [2]: void call(). Він походить від інтерфейсів [Action] та [1, 3]. Інтерфейс [Action] не має методів. Такі інтерфейси називаються маркерними інтерфейсами [4]. Вони використовуються переважно для написання коду: if(c instanceOf(Action)) {...}. Інтерфейс [Action], у свою чергу, походить від маркерного інтерфейсу [Function] [4-6];
 

Ми проілюструємо інтерфейс [Action0] за допомогою наступного коду (Приклад01):


package dvp.rxjava.lamdbas;

import rx.functions.Action0;

public class Exemple01 {
  public static void main(String[] args) {
    // Дія 0
    Action0 a01 = new Action0() {
      @Override
      public void call() {
        System.out.println("anonymous a01.call");
      }
    };
    Action0 a02 = () -> System.out.println("lambda ao2.call");
    // перегляди
    a01.call();
    a02.call();
  }
}
  • рядки 8–13: реалізація інтерфейсу [Action0] за допомогою анонімного класу;
  • рядки 8–13: реалізація інтерфейсу [Action0] за допомогою лямбда-виразу;

Результати такі:

anonymous a01.call
lambda ao2.call

6.2. Приклад-02, 03: функціональний інтерфейс [Actioni]

  

Інтерфейс [Action1] має такий вигляд:

 

Проілюструємо це за допомогою такого коду (Приклад 02):


package dvp.rxjava.lamdbas;

import rx.functions.Action1;

public class Exemple02 {
  public static void main(String[] args) {
    // Дія1
    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));

    // виконання
    a10.call(20);
    a11.call(17.4);
  }
}

що дає такий результат:

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

Загалом, [Actioni] (0<=i<=9) — це функціональний інтерфейс, що має єдиний метод із сигнатурою: void call(T1 t1, T2 t2, ..., Ti ti). Ось приклад для [Action2] (Приклад03):


package dvp.rxjava.lamdbas;

import rx.functions.Action2;

public class Exemple03 {
  public static void main(String[] args) {
    // Дія 2
    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);
    // виконання
    a20.call(10,11.3);
    a21.call(5,5.6);
  }
}

Отриманий результат такий:

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

6.3. Приклади-04, 05: функціональний інтерфейс [Funci]

  

Інтерфейс [Func0] виглядає так:

 

Цього разу метод [call] інтерфейсу повертає результат типу R.

Проілюструємо цей інтерфейс за допомогою такого коду:


package dvp.rxjava.lamdbas;

import rx.functions.Func0;

public class Exemple04 {
  public static void main(String[] args) {
    // Функція0
    Func0<String> f00 = new Func0<String>() {
      @Override
      public String call() {
        return "anonymous f00.call";
      }
    };
    Func0<String> f01 = () -> "lambda f01.call";
    // виконання
    System.out.println(f00.call());
    System.out.println(f01.call());
  }
}

що дає такі результати:

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

Загалом, [Funci] (0<=i<=9) — це функціональний інтерфейс, що має єдиний метод із сигнатурою: R call(T1 t1, T2 t2, ..., Ti ti). Ось приклад для [Func2] (Приклад05):


package dvp.rxjava.lamdbas;

import rx.functions.Func2;

public class Exemple05 {
  public static void main(String[] args) {
    // Функція2
    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);
    // перегляди
    System.out.println(f20.call(10,10.2));
    System.out.println(f21.call(100, 100.3));
  }
}

що дає такі результати:

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