⬆️ ⬇️

How flexible are our knowledge of Rx operators?

RxJava is gaining more and more popularity at this time. Many libraries for Java and Android are written on it, and the possession of knowledge in this area has become synonymous with being chosen. In the summary line with a description of what you are special in reactive programming raises your attractiveness to employers in front of your competitors.



And so I also decided to join this trend, to master and begin to use RxJava in my projects. In the process of reading several books and articles, everything was absolutely clear. "This knowledge and truth will shorten the code many times and give readability," I thought. But as soon as the books were finished and I sat down to rewrite my project for reactivity, it became clear that I don’t even know where to start ...



A lot of time was spent on practice and wandering in the operators. For greater efficiency, I came up with several tasks for myself, and set myself the goal of solving them, using only the Rx operators. I suggest you also test your knowledge!



If you consider yourself an expert in this area - open the IDE and try to solve five problems. It is assumed that you have basic knowledge and easily write a simple Observable. But let's agree - do not peek into the solution immediately! After all, confident knowledge is born only in hard work. In these tasks I will not conduct a description of the operators that were used. If any tasks cause difficulties - just stop - look here and try to choose the operator who will help you solve the desired task.

')

Let's start with a very simple task:



Task 1:



You have a list of cities packed in a List container. It is necessary to print it.



Initial data:



List<String> cities = Arrays.asList("", "", "", ""); 


What the result should see in the console:



city ​​of paris

city ​​of london

city ​​of rome

Moscow city



Decision:
 Observable.from(list) .map(s -> " "+s) .subscribe(System.out::println); 




The task is simple! I bet you solved it instantly. Let's try something more complicated.



Task 2:



You have a list of cities and countries packed in List containers. It is necessary to display a list in alphabetical order, in the format of <city name> - capital <country name> to print.



Initial data:



 List<String> cities = Arrays.asList("", "", "", ""); List<String> countries = Arrays.asList("", "", "", ""); 


As a result, we expect to see in the console:



London is the capital of England

Moscow is the capital of Russia

Paris is the capital of France

Rome is the capital of Italy



Decision:
 Observable.from(countries) .map(s -> s.substring(0, s.length() - 1).concat("")) .zipWith(cities, (country, city) -> city+" -  "+country) .toSortedList() .flatMap(Observable::from) .subscribe(System.out::println); 


Task 3:



Print all prime numbers less than one hundred.



For reference:



Suddenly, someone forgot - prime numbers are those that are divided without remainder only by themselves and by one. 0 and 1 are not considered to be primes.



Initial data:



To facilitate the task - a method for determining a prime number:



 private boolean isPrime(int n) { for(int i=2; i<n; i++) { if (n % i == 0) return false; } return true; } 


What the result should see in the console:



2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97



Decision
 Observable.range(0, Integer.MAX_VALUE) .skip(2) .filter(this::isPrime) .takeWhile(integer -> integer < 100) .map(String::valueOf) .reduce((s1, s2) -> s1+" "+s2) .subscribe(System.out::println); 




Task 4:



Determine which numbers in the range from 1 to 20 are divided without a balance by 3 and 7, respectively.



Initial data:



For reference, I used this method to separate into different types of dividers:



 private int whatDivider(int n) { if (n % 3 == 0) return 3; if (n % 7 == 0) return 7; return 0; } 


What the result should see in the console:



Divisible into 3: 3 6 9 12 15 18

Divisible by 7: 7 14



Decision:
 Observable.range(1, 20) .groupBy(this::whatDivider) .filter(observable -> observable.getKey() != 0) .subscribe(observable -> observable .map(String::valueOf) .reduce((s1, s2) -> s1+" "+s2) .map(s -> "    "+observable.getKey()+": "+s) .subscribe(System.out::println)); 




Task 5:



It is necessary to find the sum of the first ten members of the Fibonacci series.



For reference:



The Fibonacci series - each subsequent number is equal to the sum of the two previous numbers, and the first ten members of its series are 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, and their sum is 88.



Initial data:



To solve the problem, I used the Pair class written next to it:



 private static class Pair { final int n1; final int n2; Pair(int n1, int n2) { this.n1 = n1; this.n2 = n2; } } 


If you manage to do without him - he will be glad to learn from you!



What the result should see in the console:



88



Decision:
 Observable.range(0, 9) .map(integer -> new Pair(0, 1)) .scan((source, result) -> new Pair(source.n2, source.n1 + source.n2)) .map(pair -> pair.n2) .reduce((integer, integer2) -> integer + integer2) .subscribe(System.out::println); 




If your decisions are more concise than are given here - write in the comments, I will be glad to learn new ways, since I do not pretend to have absolute knowledge in the field of Rx and I just learn. Write if you like, there is still a cycle of tasks with the use of custom operators, and if you are interested, I will try to continue the idea in the next articles.

Source: https://habr.com/ru/post/324106/



All Articles