Tuesday, November 15, 2016

Java 8 : Using Filters, Maps, Streams and Foreach to apply Lambdas to Java Collections!


Bulk operations: map, foreach, filter streams

As the original change spec says, the purpose of bulk operations is to “add functionality to the Java Collections Framework for bulk operations upon data. […] Operations upon data are generally expressed as lambda functions”. This quote reveals the actual goal of lambdas and shifts the focus of Java 8 release for me: the most important feature is actually the new way of using collections – expressing operations that could be executed concurrently and lambdas are just the better tool for expressing the operations.

Internal vs External Iteration: for vs. foreach

Historically, Java collections were not capable to express internal iteration as the only way to describe iteration flow was the for (or while) loop. For describing the internal iteration we would use libraries, such as LambdaJ:
List persons = asList(new Person("Joe"), new Person("Jim"), new Person("John"));
forEach(persons).setLastName("Doe");
In the example above, we do not actually say how the last name should be set to each individual person – maybe the operation could be performed concurrently. Now we could could express the operations in a similar way with Java 8:
persons.forEach(p -> p.setLastName("Doe"))
The Java 8 forEach operation is avaiable on any list object and it accepts a function to work on every element of the list.
The internal iteration isn’t that much related to bulk operations over collections. This is rather a minor feature that gives us an idea of what will be the effect of syntax changes. What is actually interesting in regards to bulk data operations is the new Stream API. Further in this post we’ll show how to filter a list or a Java 8 stream and how to convert a stream to a regular set or a list.

Java 8 Stream API: map, filter, foreach

The new java.util.stream package has been added to JDK which allows us to perform filter/map/reduce-like operations with the collections in Java 8.
The Stream API would allow us to declare either sequential or parallel operations over the stream of data:
List<Person> persons = … 

// sequential version
Stream<Person> stream = persons.stream();
 
//parallel version 
Stream<Person> parallelStream = persons.parallelStream(); 
The java.util.stream.Stream interface serves as a gateway to the bulk data operations. After the reference to a stream instance is acquired, we can perform the interesting tasks with the collections.

Filter

Filtering a stream of data is the first natural operation that we would need. Stream interface exposes a filter method that takes in a Predicate (http://javadocs.techempower.com/jdk18/api/java/util/function/Predicate.html ) SAM that allows us to use lambda expression to define the filtering criteria:
List<Person> persons = …
Stream<Person> personsOver18 = persons.stream().filter(p -> p.getAge() > 18);
Now the thing is that often you want to filter a List just like in the example above. Then you can easily convert the list to a stream, filter and collect the results back to a list if necessary.

Map

Assume we now have a filtered data that we can use for the real operations, say transforming the objects. The map operations allows us to apply a function (http://javadocs.techempower.com/jdk18/api/java/util/function/Function.html ), that takes in a parameter of one type, and returns something else. First, let’s see how it would have been described in the good ‘ol way, using an anonymous inner class:
Stream students = persons.stream()
      .filter(p -> p.getAge() > 18)
      .map(new Function<Person, Student>() {
                  @Override
                  public Student apply(Person person) {
                     return new Student(person);
                  }
              });
Now, converting this example into a lambda syntax we get the following:
Stream map = persons.stream()
        .filter(p -> p.getAge() > 18)
        .map(person -> new Student(person));
And since the lambda that is passed to the map method just consumes the parameter without doing anything else with it, then we can transform it further to a method reference:
Stream map = persons.stream()
        .filter(p -> p.getAge() > 18)
        .map(Student::new);

Collect: converting stream to list

While stream abstraction is continuous by its nature, we can describe the operations on streams but to acquire the final results we have to collect the data somehow. The Stream API provides a number of “terminal” operations. The collect() method is one of those terminals that allows us to collect the results of the operations:
List students = persons.stream()
        .filter(p -> p.getAge() > 18)
        .map(Student::new)
        .collect(new CollectorList
>() { … });
Fortunately, in most cases you wouldn’t need to implement the Collectorinterfaces yourself. Instead, there’s a Collectors utility class for convenience:
List students = persons.stream()
        .filter(p -> p.getAge() > 18)
        .map(Student::new)
        .collect(Collectors.toList());
Or in case if we would like to use a specific collection implementation for collecting the results:
List students = persons.stream()
        .filter(p -> p.getAge() > 18)
        .map(Student::new)
        .collect(Collectors.toCollection(ArrayList::new));
In the example above you see how we collect Java 8 stream to a list. In the same way you can easily convert your stream to a set or a map using something like: Collectors.toCollection(HashSet::new)).

Parallel and Sequential Streams

One interesting feature of the new Stream API is that it doesn’t require to operations to be either parallel or sequential from beginning till the end. It is possible to start consuming the data concurrently, then switch to sequential processing and back at any point in the flow:
List students = persons.stream()
        .parallel()
        .filter(p -> p.getAge() > 18)  // filtering will be performed concurrently
        .sequential()
        .map(Student::new)
        .collect(Collectors.toCollection(ArrayList::new));
The hidden agenda here is that the concurrent part of data processing flow will manage itself automatically, (hopefully) without requiring us to deal with the concurrency issues.

Sunday, November 6, 2016

Java 9 - Key features with examples


  1. Java 9 REPL (JShell)
  2. Factory Methods for Immutable List, Set, Map and Map.Entry
  3. Private methods in Interfaces
  4. Java 9 Module System
  5. Process API Improvements
  6. Try With Resources Improvement
  7. CompletableFuture API Improvements
  8. Reactive Streams
  9. Diamond Operator for Anonymous Inner Class
  10. Optional Class Improvements
  11. Stream API Improvements
  12. Enhanced @Deprecated annotation
  13. HTTP 2 Client
  14. Мulti-Resolution Image API
  15. Miscellaneous Java 9 Features
Oracle Corporation is going to release Java SE 9 around end of March 2017. In this post, I’m going to discuss about “Java 9 Features” briefly with some examples.
  1. Java 9 REPL (JShell)

    Oracle Corp has introduced a new tool called “jshell”. It stands for Java Shell and also known as REPL (Read Evaluate Print Loop). It is used to execute and test any Java Constructs like class, interface, enum, object, statements etc. very easily.
    We can download JDK 9 EA (Early Access) software from https://jdk9.java.net/download/
    G:\>jshell
    |  Welcome to JShell -- Version 9-ea
    |  For an introduction type: /help intro
    
    
    jshell> int a = 10
    a ==> 10
    
    jshell> System.out.println("a value = " + a )
    a value = 10
    If you want to know more about REPL tool, Please go through Java 9 REPL Basics (Part-1) and Java 9 REPL Features (Part-2).
  2. Factory Methods for Immutable List, Set, Map and Map.Entry

    Oracle Corp has introduced some convenient factory methods to create Immutable List, Set, Map and Map.Entry objects. These utility methods are used to create empty or non-empty Collection objects.
    In Java SE 8 and earlier versions, We can use Collections class utility methods like unmodifiableXXX to create Immutable Collection objects. For instance, if we want to create an Immutable List, then we can use Collections.unmodifiableList method.
    However these Collections.unmodifiableXXX methods are very tedious and verbose approach. To overcome those shortcomings, Oracle corp has added couple of utility methods to List, Set and Map interfaces.
    List and Set interfaces have “of()” methods to create an empty or no-empty Immutable List or Set objects as shown below:
    Empty List Example
    List immutableList = List.of();
    Non-Empty List Example
    List immutableList = List.of("one","two","three");
    Map has two set of methods: of() methods and ofEntries() methods to create an Immutable Map object and an Immutable Map.Entry object respectively.
    Empty Map Example
    jshell> Map emptyImmutableMap = Map.of()
    emptyImmutableMap ==> {}
    Non-Empty Map Example
    jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
    nonemptyImmutableMap ==> {2=two, 3=three, 1=one}
    If you want to read more about these utility methods, please go through the following links:
  3. Private methods in Interfaces

    In Java 8, we can provide method implementation in Interfaces using Default and Static methods. However we cannot create private methods in Interfaces.
    To avoid redundant code and more re-usability, Oracle Corp is going to introduce private methods in Java SE 9 Interfaces. From Java SE 9 on-wards, we can write private and private static methods too in an interface using ‘private’ keyword.
    These private methods are like other class private methods only, there is no difference between them.
    public interface Card{
    
      private Long createCardID(){
        // Method implementation goes here.
      }
    
      private static void displayCardDetails(){
        // Method implementation goes here.
      }
    
    }
    If you want to read more about this new feature, please go through this link: Java 9 Private methods in Interface.
  4. Java 9 Module System

    One of the big changes or java 9 feature is the Module System. Oracle Corp is going to introduce the following features as part of Jigsaw Project.
    • Modular JDK
    • Modular Java Source Code
    • Modular Run-time Images
    • Encapsulate Java Internal APIs
    • Java Platform Module System
    Before Java SE 9 versions, we are using Monolithic Jars to develop Java-Based applications. This architecture has lot of limitations and drawbacks. To avoid all these shortcomings, Java SE 9 is coming with Module System.
    JDK 9 is coming with 92 modules (may change in final release). We can use JDK Modules and also we can create our own modules as shown below:
    Simple Module Example
    module com.foo.bar { }
    Here We are using ‘module’ to create a simple module. Each module has a name, related code and other resources.
    To read more details about this new architecture and hands-on experience, please go through my original tutorials here:
    • Java 9 Module System Basics
    • Java 9 Module System Examples
  5. Process API Improvements

    Java SE 9 is coming with some improvements in Process API. They have added couple new classes and methods to ease the controlling and managing of OS processes.
    Two new interfcase in Process API:
    • java.lang.ProcessHandle
    • java.lang.ProcessHandle.Info
    Process API example
     ProcessHandle currentProcess = ProcessHandle.current();
     System.out.println("Current Process Id: = " + currentProcess.getPid());
    If you want to read more about this new API, please go through my original tutorial at: Java SE 9: Process API Improvements.
  6. Try With Resources Improvement

    We know, Java SE 7 has introduced a new exception handling construct: Try-With-Resources to manage resources automatically. The main goal of this new statement is “Automatic Better Resource Management”.
    Java SE 9 is going to provide some improvements to this statement to avoid some more verbosity and improve some Readability.
    Java SE 7 example
    void testARM_Before_Java9() throws IOException{
     BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
     try (BufferedReader reader2 = reader1) {
       System.out.println(reader2.readLine());
     }
    }
    Java 9 example
    void testARM_Java9() throws IOException{
     BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
     try (reader1) {
       System.out.println(reader1.readLine());
     }
    }
    To read more about this new feature, please go through my original tutorial at: Java 9 Try-With-Resources Improvements
  7. CompletableFuture API Improvements

    In Java SE 9, Oracle Corp is going to improve CompletableFuture API to solve some problems raised in Java SE 8. They are going add to support some delays and timeouts, some utility methods and better sub-classing.
    Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
    Here delayedExecutor() is static utility method used to return a new Executor that submits a task to the default executor after the given delay.
    To read more about this feature, please go through my original tutorial at: Java SE 9: CompletableFuture API Improvements
  8. Reactive Streams

    Now-a-days, Reactive Programming has become very popular in developing applications to get some beautiful benefits. Scala, Play, Akka etc. Frameworks has already integrated Reactive Streams and getting many benefits. Oracle Corps is also introducing new Reactive Streams API in Java SE 9.
    Java SE 9 Reactive Streams API is a Publish/Subscribe Framework to implement Asynchronous, Scalable and Parallel applications very easily using Java language.
    Java SE 9 has introduced the following API to develop Reactive Streams in Java-based applications.
    • java.util.concurrent.Flow
    • java.util.concurrent.Flow.Publisher
    • java.util.concurrent.Flow.Subscriber
    • java.util.concurrent.Flow.Processor
    If you want to read more about this new API, please go through my original tutorials at: Introduction to Reactive Programming and Java SE 9: Reactive Streams.
  9. Diamond Operator for Anonymous Inner Class

    We know, Java SE 7 has introduced one new feature: Diamond Operator to avoid redundant code and verbosity, to improve readability. However in Java SE 8, Oracle Corp (Java Library Developer) has found that some limitation in the use of Diamond operator with Anonymous Inner Class. They have fixed that issues and going to release as part of Java 9.
      public List getEmployee(String empid){
         // Code to get Employee details from Data Store
         return new List(emp){ };
      }
    Here we are using just “List” without specifying the type parameter. To read more details about this improvement, please go through my original tutorial at: Java SE 9: Diamond Operator improvements for Anonymous Inner Class
  10. Optional Class Improvements

    In Java SE 9, Oracle Corp has added some useful new methods to java.util.Optional class. Here I’m going to discuss about one of those methods with some simple example: stream method
    If a value present in the given Optional object, this stream() method returns a sequential Stream with that value. Otherwise, it returns an Empty Stream.
    They have added “stream()” method to work on Optional objects lazily as shown below:
    Stream<Optional> emp = getEmployee(id)
    Stream empStream = emp.flatMap(Optional::stream)
    Here Optional.stream() method is used convert a Stream of Optional of Employee object into a Stream of Employee so that we can work on this result lazily in the result code.
    To understand more about this feature with more examples and to read more new methods added to Optional class, please go through my original tutorial at: Java SE 9: Optional Class Improvements
  11. Stream API Improvements

    In Java SE 9, Oracle Corp has added four useful new methods to java.util.Stream interface. As Stream is an interface, all those new implemented methods are default methods. Two of them are very important: dropWhile and takeWhile methods
    If you are familiar with Scala Language or any Functions programming language, you will definitely know about these methods. These are very useful methods in writing some functional style code. Let us discuss about takeWhile utility method here.
    This takeWhile() takes a predicate as an argument and returns a Stream of subset of the given Stream values until that Predicate returns false for first time. If first value does NOT satisfy that Predicate, it just returns an empty Stream.
    jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                     .forEach(System.out::println);
    1
    2
    3
    4
    To read more about takeWhile and dropWhile methods and other new methods, please go through my original tutorial at: Java SE 9: Stream API Improvements
  12. Enhanced @Deprecated annotation

    In Java SE 8 and earlier versions, @Deprecated annotation is just a Marker interface without any methods. It is used to mark a Java API that is a class, field, method, interface, constructor, enum etc.
    In Java SE 9, Oracle Corp has enhanced @Deprecated annotation to provide more information about deprecated API and also provide a Tool to analyse an application’s static usage of deprecated APIs. They have add two methods to this Deprecated interface: forRemoval and since to serve this information.
    Read my original tutorial at: Java SE 9: Enhanced @Deprecated annotation to see some useful examples.
  13. HTTP 2 Client

    In Java SE 9, Oracle Corp is going to release New HTTP 2 Client API to support HTTP/2 protocol and WebSocket features. As existing or Legacy HTTP Client API has numerous issues (like supports HTTP/1.1 protocol and does not support HTTP/2 protocol and WebSocket, works only in Blocking mode and lot of performance issues.), they are replacing this HttpURLConnection API with new HTTP client.
    They are going to introduce new HTTP 2 Client API under “java.net.http” package. It supports both HTTP/1.1 and HTTP/2 protocols. It supports both Synchronous (Blocking Mode) and Asynchronous Modes. It supports Asynchronous Mode using WebSocket API.
    We can see this new API at: http://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html
    HTTP 2 Client Example
    jshell> import java.net.http.*
    
    jshell> import static java.net.http.HttpRequest.*
    
    jshell> import static java.net.http.HttpResponse.*
    
    jshell> URI uri = new URI("http://rams4java.blogspot.co.uk/2016/05/java-news.html")
    uri ==> http://rams4java.blogspot.co.uk/2016/05/java-news.html
    
    jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
    response ==> java.net.http.HttpResponseImpl@79efed2d
    
    jshell> System.out.println("Response was " + response.body(asString()))
    Please go through my original tutorial at: Java SE 9: HTTP 2 Client to understand HTTP/2 protocol & WebSocket, Benefits of new API and Drawbacks of OLD API with some useful examples.
  14. Мulti-Resolution Image API

    In Java SE 9, Oracle Corp is going to introduce a new Мulti-Resolution Image API. Important interface in this API is MultiResolutionImage . It is available in java.awt.image package.
    MultiResolutionImage encapsulates a set of images with different Height and Widths (that is different resolutions) and allows us to query them with our requirements.
    Please go through my original tutorial at: Java SE 9: Мulti-Resolution Image API to understand this new API more with some examples.
  15. Miscellaneous Java 9 Features

    In this section, I will just list out some miscellaneous Java SE 9 New Features. I’m NOT saying these are less important features. They are also important and useful to understand them very well with some useful examples.
    As of now, I did not get enough information about these features. That’s why I am going list them here for brief understanding. I will pickup these Features one by one and add to above section with a brief discussion and example. And final write a separate tutorial later.
    • GC (Garbage Collector) Improvements
    • Stack-Walking API
    • Filter Incoming Serialization Data
    • Deprecate the Applet API
    • Indify String Concatenation
    • Enhanced Method Handles
    • Java Platform Logging API and Service
    • Compact Strings
    • Parser API for Nashorn
    • Javadoc Search
    • HTML5 Javadoc