Мир ReactiveX состоит из двух частей: источники данных — Observable, и потребители — Subscriber. В этой заметке мы рассмотрим несколько простых действий, которые можно с ними сделать.

Observable очень похож на конвейер, по которому едут разные «штуки», а вдоль конвейера стоят роботы и с этими «штуками» выполняют всевозможные операции. Один робот — одна операция. К Observable можно добавить несколько роботов, получится новый Observable.

Subscriber — он и в Африке потребитель, получает по одной «штуке» с конвейера и делает с ней что хочет.

Самый простой способ создать Observable — это перечислить элементы, которые будут положены на конвейер, явно:

Observable<string> observable = Observable
    .just("one", "two", "three")

Теперь можно описать потребителя:

observable.subscribe(s -> System.out.println(s))

В итоге мы получили конструкцию, которая выкладывает на конвейер последовательно строки “one”, “two” и “three”, тут же их с конвейера забирает и печатает.

Добавим «робота», который заменит саму строку на ее длину. То есть к роботу будут подъезжать String, а отъезжать уже Integer. Длину мы сразу напечатаем.

Observable<integer> observable2 = observable.map(s -> s.length())
observable2.subscribe(i -> System.out.println(i))

Такой робот зовется Map, и делает он следующее:

Map

То же самое, но без лишних переменных:

Observable
    .just("one", "two", "three")
    .map(s -> s.length())
    .subscribe(i -> System.out.println(i))

Теперь попробуем сосчитать сумму чисел, едущих по конвейеру. Как можно словами описать решение?

Первое. Сумма, если нет ни одного элемента, равна 0. Звучит на первый взгляд странно, но если вспомнить состояние кошелька студента до первой зарплаты, то становится все понятно.

Второе. Когда появляется на конвейере следующее число, надо прибавить к уже известной на этот момент сумме его значение.

В итоге, когда мимо проедут все числа, мы будем знать их сумму.

Для этого используется робот под названием Reduce. Делает он следующее:

Reduce

«Звездочка» — это начальное значение, в нашем случае — это сумма, если нет ни одного элемента, то есть 0.

Observable
    .just("one", "two", "three")
    .map(s -> s.length())
    .reduce(0, (a, b) -> a + b)
    .subscribe(i -> System.out.println(i))

В качестве домашнего задания посчитайте среднюю длину. Использовать вспомогательные переменные, разумеется, нельзя. Подсказка: операций Map и Reduce для этой задачи вполне хватает.

Ссылки