Features and Enhancement in jdk1.8

Before we look into Java Stream API Examples, let’s see why it was required. Suppose we want to iterate over a list of integers and find out sum of all the integers greater than 10. All the Java Stream API interfaces and classes are in the java.util.stream package.


Prior to Java 8, the approach for getting 1 to 10 sum, it would be:


After java 8 it would be:


One more example where we will see use of IntStream. Let’s say we want to find a valid string having only alphabets.


In above program highlighted allMatch is from Stream package and chars method is added in jdk1.8.

Now we need to understand about functional programing. Java 8 supports functional programing where Stream API’s are majorly used.

Stream explanation will be discussed in later part of this chapter.


Program with Functional Programming


Program without Functional Programming


Remember for functional programming:

    A programming style that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.
    • F(x)=y or g(f(y(x))) = z
    Based on lambda calculus.( Some inputs are transformed to some output without modifying the input)
    • No iteration, No for loop, no variables

Before proceeding, one more concept we need to understand is functional interface. An interface with exactly one abstract method is called Functional Interface.

@FunctionalInterface annotation is added so that we can mark an interface as functional interface.

It is not mandatory to use it, but it’s recommended to avoid addition of extra methods accidentally. If the interface is annotated with @FunctionalInterface annotation and we try to have more than one abstract method, it throws compiler error.

Java 8 Collections API has been rewritten and new Stream API is introduced that uses a lot of functional interfaces. Java 8 has defined a lot of functional interfaces in java.util.function Package. Some of the useful java 8 functional interfaces are Consumer, Supplier, Function and Predicate.

java.lang.Runnable is a great example of functional interface with single abstract method run().


Also, since default methods are not abstract you’re free to add default methods to your functional interface as many as you like.


Below program will have compile time errors.


Try to understand below example :


Summarizing below points about functional interface.

  • Functional interface have only one abstract method, No need to count object class methods here [toString method in above example]

  • Can have any no of default methods [default methods with body]

  • Cannot have same name for default methods for those methods which are in object class [in above example toString method we just write without body]

  • @FunctionalInterface annotation is added so that we can mark an interface as functional interface which is not mandatory.

After functional interface understanding we will try to understand Lambda expressions. Lambda expression facilitates functional programming, and simplifies the development a lot.

Syntax:

    Option 1:
      Input parameter - > expression on input parameters
    Option 2:
      Function Interface = Input parameter - > expression on input parameters

Lambda expressions are used primarily to define inline implementation of a functional interface, i.e., an interface with a single abstract method only.


How to use functional interface with lambda expressions


Question: What advantage you think we get from functional interface and lambda expression here?

Answer: We can have different implementation of doOperation method inline here. Anonymous inner class can also do same but lot more code we needed to write here.

We will see different flavors to call this operation.

Example to use default method

  • We can have only static or default or abstract method in interfaces in jdk 8.

  • Static or default method will have a body

  • Only one keyword can be used at a time. Static or default

  • You can define static default methods in interface which will be available to all instances of class which implement this interface.

    • This makes it easier for you to organize helper methods in your libraries; you can keep static methods specific to an interface in the same interface rather than in a separate class.

    • This enables you to define methods out of your class and yet share with all child classes.

    • They provide you a highly desired capability of adding a capability to number of classes without even touching their code. Simply add a default method in interface which they all implement.


Example to use static default method.

Majorly we use three methods in this- map, filter and collect method

See below example :

Explanation is ,

In this example we want to filter all age greater than 30.Expectation is output should be all numbers greater than 30.

  1. Stream Method : It is converting array list of Employees into small chunks and making it ready for next processing.

  2. Map method : It is used to take out some elements from stream of collection. With example we will try to understand.

    1. ArrayList contain Employee and Employee contains age if we use map on Stream of ArrayList then we get collection of age.

    2. ArrayList contain Employee and Employee contains Phone and Phone contain mobile no as integer if we use map on Stream of ArrayList then we get collection of Phone then again use Map on Phone to get collection of mobile nos.

  3. Filter Method : It is used to filters a data from map here we can use lambda expressions to make it short. We can pass predicates as well here see next section.

  4. Collect Method : It is used to collection all elements in a list.


Below is complete example for all above methods :


Above classes were just POJO now we will see how we can do different operations with collections


Above classes were just POJO now we will see how we can do different operations with collections

How to design predicate :

In this case P can be anything may be x or y or z.

P indicates Employee in this case. Automatically it behaves like employee object.


Now to filter employees how I can use above predicate?

Above method filters employee as per predicates provided.


Some more simple examples of predicate