Java 8 Features - Quick Look



Java 8 Features - Quick Look


1.      Lambda Expressions
2.     Stream API
3.     New Date and Time API
4.     Optional
5.     Default Methods

             
1.     Lambda Expressions:

Lambda expression is a new and important feature of Java which was included in Java SE 8. It provides a clear and concise way to represent one method interface using an expression. It is very useful in collection library. It helps to iterate, filter and extract data from collection. The Lambda expression is used to provide the implementation of an interface which has functional interface. It saves a lot of code. In case of lambda expression, we don't need to define the method again for providing the implementation. Here, we just write the implementation code. Example code given below:


import java.util.Set;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.*;
import javax.crypto.spec.*;
import org.apache.commons.codec.binary.Base64;
public class LambdaExp {
        public static void main(String[] args){
                        math c1 = (int x, int y) -> x+y;
                        System.out.println(".....1........."+c1.calculation(3, 7));                     
                        math c2 = (int x, int y) -> x-y;
                        System.out.println(".....2........"+c2.calculation(8, 7));                      
                        math c3 = (int x, int y) -> x*y;
                        System.out.println(".....3........."+c3.calculation(2, 7));                     
                        math c4 = (int x, int y) -> x/y;
                        System.out.println(".....4........."+c4.calculation(7, 7));                     
                        MessageService s1 = msg->{
                                                                 System.out.println(msg.concat("Hello.."));
                                                                 return msg.concat("Hello");                        
                                                    };
                        s1.getMessage("Ravi..");
                        s1.getMessage("Sumesh..");
                        s1.getMessage("Rahul..");
        }             
        interface math{
                        int calculation(int x,int b);                            
         }            
        interface MessageService {
              String getMessage(String msg);
           }                          
        interface DataCharacters{
             void getData(String data);
        }             
        interface encryptyption {
             String encryption (final String data);
     }}

Output:
.....1.........10
.....1.........1
.....1.........14
.....1.........1
Ravi..Hello..
Sumesh..Hello..
Rahul..Hello..

2.     Stream API :

Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result.
The features of Java stream are –
·         A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
·         Streams don’t change the original data structure, they only provide the result as per the pipelined methods.
·         Each intermediate operation is lazily executed and returns a stream as a result, hence various intermediate operations can be pipelined. Terminal operations mark the end of the stream and return the result.

Different Operations On Streams :-

Intermediate Operations:

1.    map: The map method is used to returns a stream consisting of the results of applying the given function to the elements of this stream.

List number = Arrays.asList(2,3,4,5);
List square = number.stream().map(x->x*x).collect(Collectors.toList());


List<String> alphabets = Arrays.asList("ravi","raju");
List upper =  alphabets.stream().map(String::toUpperCase).collect(Collectors.toList());

List<String> list = Arrays.asList("Java8", "features");
list.stream().map(str -> str.length()).forEach(System.out::println);

2.    filter: The filter method is used to select elements as per the Predicate passed as argument.

List<Person> persons = Arrays.asList(
               new Person("Ravi", 30),
               new Person("Raju", 20)             
       );

Person result1 = persons.stream()
               .filter(x -> !"Raju".equals(x.getName()))
               .findAny()

               .orElse(null);

3.    sorted: The sorted method is used to sort the stream.

List names = Arrays.asList("Adithi","Ram","Krish");
List result = names.stream().sorted().collect(Collectors.toList());


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
                    
public class StreamBuilders {
       public static void main(String[] args)
    {
        Stream<Integer> stream1 = Stream.of(1,2,3,4,5,6,7,8,9);
        stream1.forEach(s -> System.out.println(s));
       
        Stream<Integer> stream2 = Stream.of(new Integer[]{67,78,89});
        stream2.forEach(p -> System.out.println(p));
       
        ArrayList sb = new ArrayList();
        sb.add("A");sb.add("C");sb.add("V");
        //FOR EACH
        sb.forEach(p->System.out.println(p));
       
        //FOREACH MAP
       Map<String, Integer> items = new HashMap<>();
       items.put("A", 10);
       items.put("B", 20);
       items.put("C", 30);
       items.put("D", 40);
       items.put("E", 50);
       items.put("F", 60);
      
       items.forEach((k,v)->System.out.println("Item : " + k + " Count : " + v));
       items.forEach((k,v)->{
              if("E".equals(k)){
                    System.out.println("Hello "+k);
              }
       });  
      
        List<String> memberNames = new ArrayList<>();
        memberNames.add("Amitabh");
        memberNames.add("Shekhar");
        memberNames.add("Aman");
        memberNames.add("Rahul");
        memberNames.add("Shahrukh");
        memberNames.add("Salman");
        memberNames.add("Yana");
        memberNames.add("Lokesh");
        memberNames.stream().filter((s) -> s.startsWith("A")).forEach(System.out::println);
       
        System.out.println("*****************************************");

        memberNames.stream().filter((s) -> s.startsWith("A"))
        .map(String::toUpperCase).forEach(System.out::println);
       
        System.out.println("*****************************************");
        memberNames.stream().sorted().map(String::toUpperCase)
        .forEach(System.out::println);
        System.out.println("*****************************************");
        List<String> memNamesInUppercase = memberNames.stream().sorted()
                .map(String::toLowerCase)
                .collect(Collectors.toList());

        System.out.print(memNamesInUppercase);
    }
}

Output :

1
2
3
4
5
6
7
8
9
67
78
89
A
C
V
Item : A Count : 10
Item : B Count : 20
Item : C Count : 30
Item : D Count : 40
Item : E Count : 50
Item : F Count : 60
Hello E
Amitabh
Aman
*********************************************************
AMITABH
AMAN
*********************************************************
AMAN
AMITABH
LOKESH
RAHUL
SALMAN
SHAHRUKH
SHEKHAR
YANA
*********************************************************

[aman, amitabh, lokesh, rahul, salman, shahrukh, shekhar, yana]


3.     New Date and Time API :
New date-time API is introduced in Java 8 to overcome the following drawbacks of old date-time API :
·         Not thread safe : Unlike old java.util.Date which is not thread safe the new date-time API is immutable and doesn’t have setter methods.
·         Less operations : In old API there are only few date operations but the new API provides us with many date operations.

Java 8 under the package java.time introduced a new date-time API, most important classes among them are :
·         Local : Simplified date-time API with no complexity of timezone handling.
·         Zoned: Specialized date-time API to deal with various timezones.

LocalDate/LocatTime and LocalDateTime APIUse it when time zones are NOT required.


import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.time.LocalDate;
import java.util.Calendar; 
import java.time.Instant;


public class Date {

public static void LocalDateTimeApi()
{    
    // the current date
    LocalDate date = LocalDate.now();
    System.out.println("The current date is "+date);   
    // the current time
    LocalTime time = LocalTime.now();
    System.out.println("The current time is "+time);
       
   
    // will give us the current time and date
LocalDateTime current = LocalDateTime.now();
System.out.println("current date and time : "+
current);

// to print in a particular format
DateTimeFormatter format =
DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");

  // will give us the current time and date
LocalDateTime current1 = LocalDateTime.now();
System.out.println("current date and time : "+current1);

String formatedDateTime = current.format(format);
System.out.println("in foramatted manner "+
formatedDateTime);

// printing months days and seconds

Month month = current.getMonth();
int day = current.getDayOfMonth();
int seconds = current.getSecond();
System.out.println("Month : "+month+" day : "+day+" seconds : "+seconds);

// printing some specified date
LocalDate date2 = LocalDate.of(1950,1,26);
System.out.println("the republic day :"+date2);

// printing date with current time.
LocalDateTime specificDate =
current.withDayOfMonth(24).withYear(2016);

System.out.println("specfic date with "+
"current time : "+specificDate);

// Creating a Calendar object 
        Calendar c1 = Calendar.getInstance(); 
  
        // Set Month 
        // MONTH starts with 0 i.e. ( 0 - Jan) 
        c1.set(Calendar.MONTH, 00); 
  
        // Set Date 
        c1.set(Calendar.DATE, 30); 
  
        // Set Year 
        c1.set(Calendar.YEAR, 2019); 
  
        // Creating a date object 
        // with specified time. 
        java.util.Date dateOne = c1.getTime(); 
  
        Instant inst = dateOne.toInstant(); 
  
        System.out.println( 
            "Original Date: "
            + dateOne.toString()); 
        System.out.println( 
            "Instant: " + inst);   
       
}
       

public static void main(String[] args) {
LocalDateTimeApi();
}
}

Output : 

The current date is 2020-05-08
The current time is 12:25:29.202
current date and time : 2020-05-08T12:25:29.202
current date and time : 2020-05-08T12:25:29.215
in foramatted manner 08-05-2020 12:25:29
Month : MAY day : 8 seconds : 29
the republic day :1950-01-26
specfic date with current time : 2016-05-24T12:25:29.202
Original Date: Wed Jan 30 12:25:29 IST 2019

Instant: 2019-01-30T06:55:29.219Z


4.       Optional :
Java Optional Class : Every Java Programmer is familiar with NullPointerException. It can crash your code. And it is very hard to avoid it without using too many null checks.
Java 8 has introduced a new class Optional in java.util package. It can help in writing a neat code without using too many null checks. By using Optional, we can specify alternate values to return or alternate code to run. This makes the code more readable because the facts which were hidden are now visible to the developer.
// Java program without Optional Class
public class OptionalDemo{  
    public static void main(String[] args) {  
        String[] words = new String[10];  
        String word = words[5].toLowerCase(); 
        System.out.print(word); 
    } 
}     

Output:
Exception in thread "main" java.lang.NullPointerException




// Java program with Optional Class
import java.util.Optional;  
public class OptionalDemo{  
    public static void main(String[] args) {  
        String[] words = new String[10];  
        Optional<String> checkNull = 
                      Optional.ofNullable(words[5]);  
        if (checkNull.isPresent()) {  
            String word = words[5].toLowerCase();  
            System.out.print(word);  
        } else
            System.out.println("word is null");  
    }} 

Output :
word is null

Optional is a container object which may or may not contain a non-null value. You must import java.util package to use this class. If a value is present, isPresent() will return true and get() will return the value. Additional methods that depend on the presence or absence of a contained value are provided, such as or Else() which returns a default value if value not present and if Present() which executes a block of code if the value is present. This is a value-based class, i.e their instances are :
Final and immutable (though may contain references to mutable objects).
Considered equal solely based on equals(), not based on reference equality(==).
Do not have accessible constructors.
5.     Default Methods :
 Before Java 8, interfaces could have only abstract methods. The implementation of these methods has to be provided in a separate class. So, if a new method is to be added in an interface, then its implementation code has to be provided in the class implementing the same interface. To overcome this issue, Java 8 has introduced the concept of default methods which allow the interfaces to have methods with implementation without affecting the classes that implement the interface.
Important Points:

1.    Interfaces can have default methods with implementation in Java 8 on later.
2.    Interfaces can have static methods as well, similar to static methods in classes.
3.    Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.

// A simple program to Test Interface default
// methods in java
interface TestInterface
{
    // abstract method
    public void square(int a);
  
    // default method
    default void show()
    {
      System.out.println("Default Method Executed");
    }
}
  
class TestClass implements TestInterface
{
    // implementation of square abstract method
    public void square(int a)
    {
        System.out.println(a*a);
    }
  
    public static void main(String args[])
    {
        TestClass d = new TestClass();
        d.square(4);
  
        // default method executed
        d.show();
    }
}

Output:
 16
 Default Method Executed

The default methods were introduced to provide backward compatibility so that existing interfaces can use the lambda expressions without implementing the methods in the implementation class. Default methods are also known as defender methods or virtual extension methods

Static Methods:

The interfaces can have static methods as well which is similar to static method of classes.
// A simple Java program to TestClassnstrate static
// methods in java
interface TestInterface
{
    // abstract method
    public void square (int a);
  
    // static method
    static void show()
    {
        System.out.println("Static Method Executed");
    }
}
  
class TestClass implements TestInterface
{
    // Implementation of square abstract method
    public void square (int a)
    {
        System.out.println(a*a);
    }
  
    public static void main(String args[])
    {
        TestClass d = new TestClass();
        d.square(4);
  
        // Static method executed
        TestInterface.show();
    }
}

Output:
 16
 Static Method Executed




// A simple Java program to demonstrate multiple
// inheritance through default methods.
interface TestInterface1
{
    // default method
    default void show()
    {
        System.out.println("Default TestInterface1");
    }
}
  
interface TestInterface2
{
    // Default method
    default void show()
    {
        System.out.println("Default TestInterface2");
    }
}
  
// Implementation class code
class TestClass implements TestInterface1, TestInterface2
{
    // Overriding default show method
    public void show()
    {
        // use super keyword to call the show
        // method of TestInterface1 interface
        TestInterface1.super.show();
  
        // use super keyword to call the show
        // method of TestInterface2 interface
        TestInterface2.super.show();
    }
  
    public static void main(String args[])
    {
        TestClass d = new TestClass();
        d.show();
    } }
Output:
Default TestInterface1
Default TestInterface2

Important Points:

1.    Interfaces can have default methods with implementation in Java 8 on later.
2.    Interfaces can have static methods as well, similar to static methods in classes.
3.    Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.

Default Methods and Multiple Inheritance

In case both the implemented interfaces contain default methods with same method signature, the implementing class should explicitly specify which default method is to be used or it should override the default method.

Comments

Popular posts from this blog

Why to do a POC (Proof Of Concept)