Java 9 features

Java 9 has introduced a couple of nice features. Let's try to use them? :)
1) Factory Methods for Immutable List, Set, Map and Map.Entry
You can easily create an immutable List, Set or Map by using a .of() method like this:

List<String> newList = List.of("a", "b", "c");
Set<String> newSet = Set.of("a", "b", "c");
Map<Integer, String> newMap = Map.of(1, "first", 2, "second", 3, "third");


Very convenient, I must say. On previous versions of Java you had to make a loop or use some other library to achieve the same result.

2) Reactive programming is becoming very popular these days. So, Java 9 now contains Reactive Streams API which basically is Publish/Subscribe Framework. Producer sends data to subscribers which perform some actions based on received data. For instance:

// Subscriber
import java.util.concurrent.Flow;

public class StringSubscriber implements Flow.Subscriber<String> {

    public static final int NUMBER_OF_INVOCATIONS = 1;

    private Flow.Subscription subscription;

    @Override
    public void onSubscribe(Flow.Subscription subscription) {
        this.subscription = subscription;
        this.subscription.request(NUMBER_OF_INVOCATIONS);
    }

    @Override
    public void onNext(String item) {
        System.out.println("Got a message: " + item);
        subscription.request(NUMBER_OF_INVOCATIONS);
    }

    @Override
    public void onError(Throwable throwable) {
        System.out.println(throwable.getStackTrace());
    }

    @Override
    public void onComplete() {
        System.out.println("Completed!");
    }

}

// And Publisher:
import java.util.List;
import java.util.concurrent.SubmissionPublisher;
// ...

// Let's create a Publisher
SubmissionPublisher<String> publisher = new SubmissionPublisher<>();
// Let's register a Subscriber
StringSubscriber stringSubscriber = new StringSubscriber();
publisher.subscribe(stringSubscriber);
// Let's publish same data
List<String> items = List.of("1", "2", "3", "4", "5");
items.forEach(i -> publisher.submit(i));
publisher.close();

// Result:
Publishing Items...
Got a message: 1
Got a message: 2
Got a message: 3
Got a message: 4
Got a message: 5
Completed!


Works nicely!

3) Optional can return its value as stream()

// If Optional contains a value, Optional::stream will return stream with value
Optional<String> optionalWithValue = Optional.of("1");
optionalWithValue.stream().forEach(System.out::print);
// 1

// Of Optional does not have a value - Optional::stream returns an empty stream
Optional<String> optionalWithoutValue = Optional.empty();
optionalWithoutValue.stream().forEach(System.out::print);
// Empty


4) Streams now have takeWhile() and dropWhile() methods
takeWhile() returns subset of the given stream until the condition/predicate is met. dropWhile() returns subset of the given stream which does not satisfy condition/predicate (sort of NOT takeWhile()). For instance:

IntStream stream = IntStream.range(0, 10);
stream.takeWhile(x -> x < 4).forEach(a -> System.out.print(a + " "));
// 0 1 2 3


IntStream stream2 = IntStream.range(0, 10);
stream2.dropWhile(x -> x < 4).forEach(a -> System.out.print(a + " "));
// 4 5 6 7 8 9



Komentuoti