It will be very difficult for anyone to work with the reactive streams if they neither know how to create nor transform them. It will be clearly impossible to produce any useful program.
As you may have guessed, in this tutorial, we will focus on the most common methods provided by Project Reactor to create, and transform reactive streams. I would strongly advise you to read the previous tutorial as this is a series of tutorials about Reactive Programming in Spring.
Creation Methods
There are several ways you can create a Reactive Stream.
By Listing the Items yourself
We have used this way in the previous tutorial. Here, you programmatically enter the values in the stream yourself.
Flux<String> flux1 = Flux.just("s1", "s2");
From Iterable
Flux<String> flux2 = Flux.fromIterable(Arrays.asList("s1", "s2"));
From Array
Flux<String> flux3 = Flux.fromArray(new String[]{"s2", "s3"});
Transformation Operators
This group of methods is concerned with converting or modifying items in reactive streams.
Map
The Map Operator is a function used to apply modifications on each item and then returns a stream of the modified items. Below is a diagram is taken from the ReactiveX website.
FlatMap
This transformation method is similar to the map function with a single exception, the transformation on each item is to return a reactive stream. The items of the streams produced from the transformation of each item in the original stream are then combined and returned as the result of the flatMap. This image from the ReactiveX website illustrates this.
As you can see from the diagram above, the flatMap method does not care about the order in which the resulting streams are combined. This is because it does not wait for the termination of the streams produced by each item.
ConcatMap
This method works similarly to flatMap with the exception that it takes into consideration the order of the items. It waits for the termination of the streams produced by each item before proceeding. The following diagram from the ReactiveX website.
Hands-on-code
The following code demonstrates how each of the transformation methods is used.
public class TransformationTest{ public static void main(String[] args) throws InterruptedException { Flux<String> fluxString = Flux.just("florian", "nathan"); Flux<String> fluxFromMap = fluxString.map(s -> s.toUpperCase()); Flux<Character> fluxFromFlatMap = fluxString.flatMap(s -> { List<Character> characterList = new ArrayList<>(); for (char c : s.toCharArray()) { characterList.add(c); } return Flux.fromIterable(characterList).delayElements(Duration.ofMillis(100)); }); Flux<Character> fluxFromConcatMap = fluxString.concatMap(s -> { List<Character> characterList = new ArrayList<>(); for (char c : s.toCharArray()) { characterList.add(c); } return Flux.fromIterable(characterList).delayElements(Duration.ofMillis(100)); }); // //Subscribing System.out.println("Elements in Flux using Map"); fluxFromMap.subscribe(s -> System.out.printf("%s ", s)); System.out.println("\n\nElements in Flux From FlatMap"); fluxFromFlatMap.subscribe(character -> System.out.printf("%c ",character)); //Wait for all elements Thread.sleep(1000); System.out.println("\n\nElements in Flux From ConcatMap"); fluxFromConcatMap.subscribe(character -> System.out.printf("%c ", character)); //wait for all elements Thread.sleep(1500); }
Below is the output of the code:
Elements in Flux using Map FLORIAN NATHAN Elements in Flux From FlatMap n f a l t o h r a i n a n Elements in Flux From ConcatMap f l o r i a n n a t h a n
We used the map operator to transform each name to Uppercase. The FlatMap and ConcatMap operators were both used to produce a stream of the characters from the names. You can see that characters from the stream produced through FlatMap are not in the same order as they are in the original word. While that those from the stream produce through ConcatMap are in order. This shows that ConcatMap will wait for the stream produced from each item to complete while FlatMap does not.
Conclusion
These are the most heavily used function in Spring Webflux. We will use them in the next tutorial to create a Reactive REST Controller. Hope this one was helpful. See you in the next tutorial.