Java 8 Features

 Java 8 introduced most amazing features to enhanced and improve the language's capabilities.

  • Functional Interface 
  • Lambada Expression
  • Method Reference
  • Stream API
  • Default and Static Methods in interface
  • Optional class
  • forEach() method
  • Date and Time API
  • StringJoiner
Functional Interface 
   πŸ’œ An Interface which has Single Abstract Method (SAM Interface)    
   πŸ’œ An Interface Contains any number of default, static and overridden methods. It can also declare methods of Object class.
   πŸ’œ Java 8 Introduced @FunctionalInterface annotation to giving compile time errors if break SAM contract (more than one abstract method)

//Optional annotation
@FunctionalInterface 
public interface MyFirstFunctionalInterface { 
    public void javaStudy(); 

    default void javaSwag(){
        //code here
    }
    static void javaSwag1(){
        //code here
    }
}

e.g  - Runnable (I) -> run() - Runnable interface has single abstract (run) method. 
       - Comparable (I) -> compareTo() - Comparable interface has single abstract (compareTo) method. 

Java 8 added some new Functional interfaces such as

  • Consumer - Consume one argument and not return any value. 
  • Predicate - Accept argument and return Boolean value. 
  • Function - Only a single argument and returns a value after the required processing. 
  • Supplier - Used for defining logic to generate new sequence. 

Lambda Expression

    πŸ’› Its anonymous function.
    πŸ’› It is used to implements functional interface. 
    πŸ’› It reduces the line of code.

Expression Syntax 
(Argument list) -> {statements;}
(Argument list) -> expression 
() -> expression
    
   () - Argument list - it can be empty or non-empty. 
   -> - arrow token - to link argument list to body
   {} - body - it contains expression and statement for lambda expression.

//This function takes two parameters and return their sum
(x, y) -> x + y


Method Reference 

    πŸ’šMethod reference used to refer method of Functional interface.
    πŸ’šSyntax for lambda expression that contain just one method call. 

Type of Method Reference
    
        πŸ‘‰Reference to Static method: ContainingClass::staticMethodName   
        πŸ‘‰Reference to Instance Method:  containingObject::instanceMethodName  
        πŸ‘‰Reference to Constructor:  ClassName::new  
 
interface Sayable {  
    void say();  
}  
public class MethodReference {  
    public static void saySomething(){  
        System.out.println("Hello, this is static method.");  
    }  
    public static void main(String[] args) {  
        // Referring static method  
        Sayable sayable = MethodReference::saySomething;  
        // Calling interface method  
        sayable.say();  
    }  
}

Default Method

    πŸ’™ Java 8 provide implementation of method in interface with default keyword with method name.
    πŸ’™ We can add default method without affecting the classes that implement the interface.
    πŸ’™ When 2 interface has same default method then implementing class should explicitly override default method to avoid conflict error. 
    πŸ’™ A default method is visible\usable in the object instance scope.

❓WHY? -> In Java, prior to Java 8, when a class implemented an interface, it was mandatory to provide implementations for all the interface's methods in the class. However, in Java 8, the introduction of default and static methods in interfaces allowed for the addition of new methods without requiring all implementing classes to provide implementations. This means that if an abstract method is added to an interface, it becomes mandatory for all classes that previously implemented the interface to implement that method. To address this, Java 8 introduced default methods and static methods with implementations in interface. 

public interface JavaStudyExample {
    default void javaSwag(){
        System.out.println("Hey Pushkar!! This is default method");
    }
}

πŸ‘‰ 'java.util.collection' => stream()
πŸ‘‰ 'java.util.List' => replaceAll(), sort(), indexOf()
πŸ‘‰ 'java.util.map' => forEach(), getOrDefault(), replaceAll()
πŸ‘‰ 'java.util.comparator' => reversed(), thenComparing(), nullFirst()

Static Method


πŸ’š Similar default method static method also introduced in java 8.
πŸ’š we can write implementation of method in interface with static keyword in method signature.
πŸ’š Static method cannot be override in implementation class.
πŸ’š We can access static method using Interface name.
πŸ’š Static method scope is visible/usable in interface scope.

public interface JavaStudyExample {
    static void javaSwag(){
        System.out.println("Hey Pushkar!! This is static method");
    }
}
 
πŸ‘‰ 'java.util.Predicate' => isEqual()

Optional Class

πŸ’œ Optional is container class which may or may not contain a nonnull value.
πŸ’œ If a value is present, isPresent() will return true and get() will return the value.
πŸ’œ Optional class provide methods orElse(), orElseGet() that allows you to specify default value to be used when value is absent.

Optional<String> optionalValue =                 Optional.ofNullable(someMethodReturningAString());
optionalValue.ifPresent(value -> System.out.println("Value is present: " + value));
String result = optionalValue.orElse("Default Value");

 Stream API

πŸ’› It's used for process collections of objects.
πŸ’› Stream takes input from collections, Arrays and I/O channel.
πŸ’› Don’t change original structure, only provide the result as per pipelined methods.
πŸ’› Stream Is lazy in nature (Intermediate operation does not execute till terminal operation call)

πŸ’› Three important components of Stream API are Source, one or more Intermediate operations and Terminal operations
πŸ’› These three types of components are pipelined in a sequence to make a stream work.


Intermediate Operations:
πŸ˜‹Limit & skip - Limit the n number of element in Stream & Skip  number of elements from stream.
πŸ˜‹Distinct- Remove duplicate elements.
πŸ˜‹Map - Return stream by applying given function to element of the stream. change one object into another.
πŸ˜‹FlatMap - Transform each element into multiple values and also flatten resulting stream. (If there is stream of stream then it will transform into single stream)
πŸ˜‹Filter - Filter elements as per predicate pass as argument
πŸ˜‹Sorted - Sort the stream.
πŸ˜‹Peek- Need to perform some operation before any terminal operation and return new stream for further use

Terminal Operation:
πŸ˜‹Collect- return the result of intermediate operation perform on the stream
πŸ˜‹forEach- iterate every element from stream
πŸ˜‹Reduce- reduce element of stream into single value
πŸ˜‹Count- number of element in stream
πŸ˜‹Min and max - find smallest and largest value from stream
πŸ˜‹findFirst and findAny -
πŸ˜‹anyMatch, allMatch, noneMatch-


RealTime Examples of Stream:

Employe class-

package com.java8features;


public class Employee {


public int id;


public String name;


public int age;


public String gender;


public String department;


public int yearOfJoining;


public double salary;


public Employee(int id, String name, int age, String gender, String department, int yearOfJoining, double salary) {

this.id = id;

this.name = name;

this.age = age;

this.gender = gender;

this.department = department;

this.yearOfJoining = yearOfJoining;

this.salary = salary;

}


public int getId() {

return id;

}


public String getName() {

return name;

}


public int getAge() {

return age;

}


public String getGender() {

return gender;

}


public String getDepartment() {

return department;

}


public int getYearOfJoining() {

return yearOfJoining;

}


public double getSalary() {

return salary;

}


public void setId(int id) {

this.id = id;

}


public void setName(String name) {

this.name = name;

}


public void setAge(int age) {

this.age = age;

}


public void setGender(String gender) {

this.gender = gender;

}


public void setDepartment(String department) {

this.department = department;

}


public void setYearOfJoining(int yearOfJoining) {

this.yearOfJoining = yearOfJoining;

}


public void setSalary(double salary) {

this.salary = salary;

}


@Override

public String toString() {

return "Id : " + id + ", Name : " + name + ", age : " + age + ", Gender : " + gender + ", Department : "

+ department + ", Year Of Joining : " + yearOfJoining + ", Salary : " + salary;

}

}



Stream API Methods-
package com.java8features;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.DoubleSummaryStatistics;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

public class StreamAPIMethods {

public static void main(String[] args) {
List<Employee> emps = getEmps();
List<String> names = getNamesList();

/*
* How many male and female employees are there in the organization?
*/
Map<String, Long> collect = emps.stream()
.collect(Collectors.groupingBy(Employee::getGender, Collectors.counting()));
System.out.println(collect);

/* Print the name of all departments in the organization? */
List<String> collect2 = emps.stream().map(Employee::getDepartment).distinct().collect(Collectors.toList());
System.out.println(collect2);

/* What is the average age of male and female employees? */
Map<String, Double> collect3 = emps.stream()
.collect(Collectors.groupingBy(Employee::getGender, Collectors.averagingInt(Employee::getAge)));
System.out.println(collect3);

/* Get the details of highest paid employee in the organization? */
Optional<Employee> collect4 = emps.stream()
.collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)));
System.out.println(collect4.get());

/* Get the names of all employees who have joined after 2015? */
List<String> collect5 = emps.stream().filter(e -> e.getYearOfJoining() > 2015).map(Employee::getName)
.collect(Collectors.toList());
System.out.println(collect5);

/* Count the number of employees in each department? */
Map<String, Long> collect6 = emps.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));
System.out.println(collect6);

/* What is the average salary of each department? */
Map<String, Double> collect7 = emps.stream().collect(
Collectors.groupingBy(Employee::getDepartment, Collectors.averagingDouble(Employee::getSalary)));
System.out.println(collect7);

/*
* Get the details of youngest male employee in the product development
* department?
*/
Optional<Employee> min = emps.stream().filter(e -> e.getDepartment().equalsIgnoreCase("product development"))
.min(Comparator.comparingInt(Employee::getAge));
System.out.println(min.get());

/* Who has the most working experience in the organization? */
Optional<Employee> min1 = emps.stream().min(Comparator.comparingDouble(Employee::getYearOfJoining));
System.out.println(min1.get());

/*
* How many male and female employees are there in the sales and marketing team?
*/
Map<String, Long> collect8 = emps.stream()
.filter(e -> e.getDepartment().equalsIgnoreCase("Sales And Marketing"))
.collect(Collectors.groupingBy(Employee::getGender, Collectors.counting()));
System.out.println(collect8);

/* What is the average salary of male and female employees? */

Map<String, Double> collect9 = emps.stream()
.collect(Collectors.groupingBy(Employee::getGender, Collectors.averagingDouble(Employee::getSalary)));
System.out.println(collect9);

/* List down the names of all employees in each department? */

Map<String, List<Employee>> collect10 = emps.stream().collect(Collectors.groupingBy(Employee::getDepartment));
Set<Entry<String, List<Employee>>> entrySet = collect10.entrySet();
for (Entry<String, List<Employee>> entry : entrySet) {
System.out.println("----------");
System.out.println(entry.getKey());
System.out.println("----------");
entry.getValue().stream().map(e -> e.getName()).forEach(System.out::println);
}
System.out.println("----------");
/* What is the average salary and total salary of the whole organization? */
DoubleSummaryStatistics summaryStatistics = emps.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println("AVG: " + summaryStatistics.getAverage() + " SUM: " + summaryStatistics.getSum());

/*
* Separate the employees who are younger or equal to 25 years from those
* employees who are older than 25 years.
*/

Map<Boolean, List<Employee>> collect11 = emps.stream().collect(Collectors.partitioningBy(e -> e.getAge() > 25));

System.out.println(collect11);

for (Entry<Boolean, List<Employee>> entry : collect11.entrySet()) {
if (entry.getKey()) {
System.out.println("Older than or equal to 25");
entry.getValue().stream().forEach(System.out::println);
} else {
System.out.println("Younger than 25");
entry.getValue().stream().forEach(System.out::println);
}
}

/*
* Who is the oldest employee in the organization? What is his age and which
* department he belongs to?
*/
System.out.println("----------");
Employee employee = emps.stream().collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getAge))).get();
System.out.println(employee);
System.out.println("----------");

/* Sort Examples */

List<Employee> collect12 = emps.stream().sorted((o1, o2) -> o2.getAge() - o1.getAge())
.collect(Collectors.toList());
collect12.forEach(System.out::println);
System.out.println("----------");

List<Employee> collect13 = emps.stream().sorted(Comparator.comparing(Employee::getAge).reversed())
.collect(Collectors.toList());
collect13.forEach(System.out::println);
System.out.println("----------");

List<Employee> collect14 = emps.stream().map(e -> {
e.setSalary(e.getSalary() + 1);
return e;
}).collect(Collectors.toList());
collect14.forEach(System.out::println);
System.out.println("----------");
Set<String> collect15 = names.stream().map(n-> {return n + " - " + Collections.frequency(names, n);}).collect(Collectors.toSet());
collect15.forEach(System.out::println);
System.out.println("----------");
String s = "All is Well";
Map<Character, Integer> map = new HashMap<>();
s.chars().forEach(c-> map.merge((char) c, 1, Integer::sum));
System.out.println(map);
}

public static List<Employee> getEmps() {
List<Employee> employeeList = new ArrayList<Employee>();

employeeList.add(new Employee(111, "Jiya Brein", 32, "Female", "HR", 2011, 25000.0));
employeeList.add(new Employee(122, "Paul Niksui", 25, "Male", "Sales And Marketing", 2015, 13500.0));
employeeList.add(new Employee(133, "Martin Theron", 29, "Male", "Infrastructure", 2012, 18000.0));
employeeList.add(new Employee(144, "Murali Gowda", 28, "Male", "Product Development", 2014, 32500.0));
employeeList.add(new Employee(155, "Nima Roy", 27, "Female", "HR", 2013, 22700.0));
employeeList.add(new Employee(166, "Iqbal Hussain", 43, "Male", "Security And Transport", 2016, 10500.0));
employeeList.add(new Employee(177, "Manu Sharma", 35, "Male", "Account And Finance", 2010, 27000.0));
employeeList.add(new Employee(188, "Wang Liu", 31, "Male", "Product Development", 2015, 34500.0));
employeeList.add(new Employee(199, "Amelia Zoe", 24, "Female", "Sales And Marketing", 2016, 11500.0));
employeeList.add(new Employee(200, "Jaden Dough", 38, "Male", "Security And Transport", 2015, 11000.5));
employeeList.add(new Employee(211, "Jasna Kaur", 27, "Female", "Infrastructure", 2014, 15700.0));
employeeList.add(new Employee(222, "Nitin Joshi", 25, "Male", "Product Development", 2016, 28200.0));
employeeList.add(new Employee(233, "Jyothi Reddy", 27, "Female", "Account And Finance", 2013, 21300.0));
employeeList.add(new Employee(244, "Nicolus Den", 24, "Male", "Sales And Marketing", 2017, 10700.5));
employeeList.add(new Employee(255, "Ali Baig", 23, "Male", "Infrastructure", 2018, 12700.0));
employeeList.add(new Employee(266, "Sanvi Pandey", 26, "Female", "Product Development", 2015, 28900.0));
employeeList.add(new Employee(277, "Anuj Chettiar", 31, "Male", "Product Development", 2012, 35700.0));
return employeeList;
}
public static List<String> getNamesList(){
return Arrays.asList("Pushkar","Sakshi","ABC","Sidhu", "Pushkar", "ABC","Pushkar","Pushkar","Sidhu");
}
}

Comments

Popular posts from this blog

Welcome to Java study !!!

Spring Dependency Injection