Java - 8 - Features Notes

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 39

Java 8 Features:

Java 8 new feature has been introduced to enable functional programming in Java. Java 8 very
important feature is to concise the coding in java.
1. Lambda Expression
2. Functional Interface
3. Default Methods & Static Methods
4. Predefined functional interface
a. Functional
b. Predicate
c. Consumer
d. Supplier, etc.
e. Other Additional Functional Interfaces
5. Double colon operator (::)
a. Method reference
b. Constructor reference
6. Streams
7. Date and Time API
8. Optional Class
9. StringJoiner Class
10. Nashron JavaScript engine

Lambda Expression:
The first programming language who has used Lambda expression was LISP.
The main purpose of bringing lambda expression into java programming to bring the functional
programing concept in Java.
 It is an anonymous function
Without name
Without return type
Without modifiers

Example:
()-> System.out.println ("Hello");

Example: (num1, num2)-> System.out.println(“Sum=”+num1+num2);

Example: (s)-> s.length();

Functional Interface:
An Interface that contains exactly one abstract method is known as functional interface. It can have
any number of default, static methods but can contain only one abstract method. It can also
declare methods of object class. Following are the example of interface which are having only one
abstract method.
Comparable
Comparator
Runnable
ActionListener
Callable
Single abstract methods (SAM) interfaces are known as functional interface. We can use
@FunctionalInterface annotation for making an interface explicitly. If an interface contains more
than one abstract method then is not a functional interface.

Valid:
@FunctionalInterface
interface Dream{
public void everydayDream();

Valid:
@FunctionalInterface
interface Dream{
public void everydayDream();

}
@FunctionalInterface
interface NewDream extends Dream{

Valid:
@FunctionalInterface
interface Dream{
public void everydayDream();

}
@FunctionalInterface
interface NewDream extends Dream{
public void everydayDream();
}

Invalid:
@FunctionalInterface
interface Dream{
public void everydayDream();

}
@FunctionalInterface
interface NewDream extends Dream{
public void rareDream();
}

Lambda Expression with Functional Interface:


We can provide the implementation of functional interface using lambda expression.

@FunctionalInterface
interface Dream{
public void everydayDream();

public class FunctionInterface_Demo {


public static void main(String[] args) {
Dream d=()-> System.out.println("Dream is Big");
}
}

Number Sorting Program without Lambda Expression:


Number Sorting Program with Lambda Expression:

Using filter(), stream(), collect() method for finding even numbers from the list.
Filter Collection Data with Lambda Expression:
Anonymous Inner Class:
Wherever we have a requirement of instant use then we can go for anonymous inner class.
Same program we can do it by Lambda expression approach:

Default Method in Interface:


Since JDK8 we can define a default method inside an interface. Default method is also called as
Virtual extension method or Defender method.
Consider a scenario where we have to add some functionalities (new methods) in an existing
interface which has already implemented by several class. In that situation every implemented class
has to provide the implementation on individual level.

The concept of without affecting implementation classes adding the functionality to an interface is
called default method in Java.

Rules for Default Method:


1. You can’t make object class methods as default methods in an interface, otherwise you will
get compile time error because the implementation class is already extending Object class
methods by default.
Example: interface MyInter{
default int hashCode(){
return 10;
}
}
If both interfaces have same default methods with same name, in that condition it gives an error
saying unrelated methods in the classes. To solve this problem we have one way as follow.

Live example of Default Method:


OUTPUT:

Static Method in an Interface:


Static Methods in Interface are those methods, which are defined in the interface with the keyword
static. Unlike other methods in Interface, these static methods contain the complete definition of
the function and since the definition is complete and the method is static, therefore these methods
cannot be overridden or changed in the implementation class.

If we have lots of static methods then we don’t need to define them in a class, instead we can
define them in an interface. The normal utility methods which doesn’t require any object to
perform operations, then we can define those methods in an interface.
Note: We can also define main method inside in an interface.

Predefined Functional Interface:


Predefined functional interfaces are very useful for Lambda expression.

 Predicate
 Function
 Consumer
 Supplier
Two argument Predefined Functional Interface
 BiPredicate
 BiFunction
 BiConsumer
 BiSupplier
Primitive Functional Interface
 IntPredicate
 IntFunction
 InConsumer
 IntSupplier
Note: This all Functional interfaces are introduced in Java 8 in java.util.function
package.

Predicate (I): Predicate is a Functional Interface present in java.util.Function package


to provide support for lambda expression.
This interface is having 5 functions as follows:

1. isEqual(Object targetRef): This function is used to check whether two


arguments are equal or not according to Objet.equals(Object, Object)

2. and(Predicate other): Returns a composed predicate that represents the logical


AND of this predicate and another.
3. negate(): Returns a predicate that represents the logical negation of this predicate.

4. test(): This is abstract method of Predicate interface. It evaluates true if predicate


matches the input argument.
We can validate user defined data type using predicate functions as
follows.

Wherever conditional check is required we can use Predicate. It can


be used several times throughout the program.
Using a Predicate for the Employees class to find the employees with
the salary more than 4000.
Functional (I): The most simple and general case of lambda expression is Functional interface with a
method that receives one value and return another.
Function interface another example with different data type return.

Passing user defined Object as Emp_Performance to apply function and


it returns a string.
Function Chaining:

For function chaining we have a method called as andThen().

For function chaining we have another function called as compose().

Note: Only the difference between this two functions are, in andThen() the f1 will be executed
first and then f2, but in case of compose() it is reversed.
Consumer (I): Consumer is an interface present in in java.util.function package. This is also
added in java 8 to implement functional programming. It represents a function which accept one
argument and produces a result, but this will not return anything, its return type is void.

The Consumer Interface consist of one function as follows.

void accept(T t)

Consumer example with Employee user defined object type:


Note: Consumer chaining is possible, we just have to use andThen() function for chaining.

Supplier (I): The Supplier Interface is a part of the java.util.function package which has been
introduced since Java 8, to implement functional programming in Java. It represents a function which
does not take in any argument but produces a value of type T.

This interface is having only one function that is get()


public R get();
Program for generating random numbers using Consumer Interface:

BiPredicate (I): This is a functional interface present on java.util.function package, this interface is
exactly same as Predicate interface, however it is used in a situation where you want pass two
arguments and have a conditional check based on that.

It contains a same static methods as Predicate. But test method will accept two arguments as an
input.

public Boolean test(T1 t1, T2 t2){ . . . }


BiFunction (I): This is same like Function interface except that, in this interface apply function accept
two arguments as an input and return the result.

public R apply(T1 t1, T2 t2);


BiConsumer (I): This is same like Consumer interface but it’s accept function can take two argument
as an input, but it will not return anything.

public void accept(T1 t1, T2 t2);


Primitive version of Predicate Type:
IntPredicate: This type of functional interface is used for primitive data type, this type of
functional interface doesn’t require any type to be mentioned explicitly while creating Predicate.
Note: Similarly we have other primitive Predicate for Double, Long as follows:
DoublePredicate
LongPredicate

Primitive version of Function Type:


IntFunction(I): This is a primitive version of Function type, it is used for integer primitive types, it cant
accept integer and can return any value.
Note: Similarly we have other primitive Function for Double, Long as follows:
DoubleFunction
LongFunction

DoubleToIntFunction (I): This type of primitive type Function is used to convert Double to Int, in other
words it accepts Double as an argument and return Int as a return type.

It contains the following function:

public int applyAsInt (double d){ . . . }

Method reference and Constructor reference:


Method reference and constructor reference are alternative to Lambda expression. We can use ::
operator for method and constructor reference.
Note: Code reusability is the biggest advantage of Method reference.
Rules: While referencing a method you need to make sure that arguments of the method are same,
however return type and the access modifiers can differ.

Constructor Reference: You can refer a constructor by using the new keyword. Here, we are referring
constructor with the help of functional interface.

Streams:
In Java 8 a new additional package has introduced called java.util.stream. This package is
consist of classes, interfaces and enums to allow functional operations on elements.

Important points about Stream:


1. Stream does not store elements, it simply conveys elements through a computational
operation.
2. Stream is functional in nature, operations performed on Stream will not affect the original
source
3. The Streams are only visited once, during the life of a stream. Like an iterator you have to
create the stream once again whenever you need it.

We can do many operations on streams such as filtering, converting, and printing


filter() Method:

reduce() Method:
This method takes the sequence of input elements and combines them into a single summary result
by repeated operations.
Java Stream Example: Find Max and Min Product Price
Java Stream Example: count() Method in Collection

Note: We can convert List to a Set and vice versa by using Collectors.toSet() and Collectors.toList()
methods.

Java 8 Date and Time:


Java has introduced a new Date and Time API since Java 8. The java.time package contains Java
8 Date and Time classes.

1. LocalDate Class
2. LocalTime Class
3. LocalDateTime Class
4. Period Class
5. Duration Class
6. Clock Class
7. Instant Class
8. Year Class
9. ZonedDateTime Class
10. Month Enum

LocalDate:

LocalTime:
LocalDateTime:
LocalDateTime class is immutable date-time object that represents date-time, with the default date-
time format as follows. yyyy-MM-dd-HH-mm-ss.zz

Java OffsetTime:
Period:
Period class is used to measure time in years, months, days.

of():

Optional Class in Java 8:


Every Java programmer is familiar with NullPointerExaception. It can crash your code and it is very
hard to avoid without so many null checks. Java 8 has introduced an new Class called as Optional
class which helps you to write the neat code without using too many null checks. Now you can have
an alternate values to return. This makes code more readable because the facts which were hidden
now they are visible to a developer.
Without Optional class:

With Optional Class:

Advantages of Java 8 Optional:

1. Null checks are not required.


2. No more NullPointerException at run-time.
3. We can develop clean and neat APIs.
4. No more Boiler plate code
Various methods in Optional class:

OUTPUT:

Basically Optional class is a container object which may hold a non-null value or null value. If the value
is present then isPresnt() will return true and get() will return the value.
Other additional methods are depends on presence and absence of a contained value are provided
such as orElse() (return default value if value is not present) and ifPresent() (execute the
block of code if value is present).

1. empty()  returns an empty Optional instance, no value is present in it


2. of()  return the Optional with non-empty value, if the value is null then it throws
NullPointerException
3. ofNullable()  returns an Optional with specified value, return an empty optional if
the value id null.
4. get()  return the value present in this optional otherwise throw an error saying
NoSuchElementException.
5. isPresent()  return true if the value is present otherwise return false
6. ifPresnt()  if value present, invoke consumer with the value, otherwise do nothing.
7. filter()  If a value is present, and the value matches given predicate, return Optional
describing the value, otherwise return an empty optional, it also return null if the predicate is
null.
8. map() If a value is present, apply the provided mapping function to it, and if the result is
non-null, return an Optional describing the result. Otherwise return an empty Optional. Also
return null if the function is null.
9. flatMap()  If a value is present, apply the provided Optional-bearing mapping function
to it, return that result, otherwise return an empty Optional. This method is similar to
map(Function), but the provided mapper is one whose result is already an Optional, and if
invoked, flatMap does not wrap it with an additional Optional.
10. orElse()  Return the value if present, otherwise return other.
StringJoiner Class:
Java added a new final class called StringJoiner, it is used to construct a sequence of characters by
using a delimiter. Now you can pass delimiter like comma(,), hyphen(-) etc. You can also pass prefix
and suffix to char sequence.
StringJoiner with prefix and postfix:

You might also like