Friday, April 19, 2019

Java 9 - Try with resources Improvement


Java 9  -  Try with resources Improvement



In this blog, I’ll discuss about try with resources which was introduced with JDK 7 and what enhancement has been done in JDK 9.

Try with resources is a great feature which was introduced in JDK 7 that helps in closing resources automatically after being used.

Any class can be used as resources if that class implements AutoClosable Interface.

Advantages
  • As try with resources closes all the resources file Automatically which prevents memory leaks.
  • More readable code as you don’t have to write unnecessary code. 

Let’s understand it with an example

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * This class will explain the try with resources which was introduced with
 * JDK7.
 *
 * @author AbdulWaheed18@gmail.com
 *
 */
public class ExmapleWithJava7 {

       public static void main(String[] args) throws FileNotFoundException {

             try (FileOutputStream fileStream = new FileOutputStream("App.log");) {
                    String logMessage = "[INFO] DATA NEED TO BE WRITTEN";
                    byte logMessageInBytes[] = logMessage.getBytes();
                    fileStream.write(logMessageInBytes);
                    System.out.println("Updated log files.");
             } catch (Exception e) {
                    // handle error
             }
       }
}

With JDK7, we have to declared all resources within try block but which is not possible for every resource like DB connection. To use DB connection, we have to close the resources explicitly in finally block which was an obvious bug.

With the JDK 9 enhancement, you can just pass the reference in try block without declaring within try block.

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

/**
 * This class will explain enhancement of try with resources block which was
 * introduced with JDK9 .
 *
 * @author AbdulWaheed18@gmail.com
 *
 */
public class ExmapleUsingJava9 {

       public static void main(String[] args) throws FileNotFoundException {
             FileOutputStream fileStream = new FileOutputStream("App.log");
             try (fileStream) {
                    String logMessage = "[INFO] DATA NEED TO BE WRITTEN";
                    byte logMessageInBytes[] = logMessage.getBytes();
                    fileStream.write(logMessageInBytes);
                    System.out.println("Updated log files.");
             } catch (Exception e) {
                    // handle error
             }
       }
}

You can download the Source code from here.

Happy Coding…!!!





Sunday, April 7, 2019

Supplier Functional Interface - JAVA 8


Supplier Functional Interface


Supplier is an in-built functional interface introduced in Java 8 in the java.util.function package. Supplier does not expect any input but returns the output. This interface can be handy where you want to generate some data like OTP, currentTime or even GUID
The functional method of Supplier is get(T t).
Here is a simple source code of java.util.function.Supplier

@FunctionalInterface
public interface Supplier<T> {
    /**
     * Gets a result.
     * @return a result
     */
    T get();
}
Where T get () is an abstract method where T is the return type of the function.

Example 1:

import java.util.Date;
import java.util.function.Supplier;

public class SupplierExample {

       public static void main(String[] args) {

             // Calling Supplier Functional Interface without using Lambda Expression
             SystemDate date = new SystemDate();
             System.out.println("System Date: " + date.get());

             // Using Lambda Expression
             Supplier<Date> supplier = () -> new Date();
             System.out.println("Using lambda, System Date: " + supplier.get());
       }

}

class SystemDate implements Supplier<Date> {

       @Override
       public Date get() {
             return new Date();
       }
}

Output:
System Date: Sun Apr 07 17:37:49 IST 2019
Using lambda, System Date: Sun Apr 07 17:37:49 IST 2019


This interface doesn’t contains any default or static method

That’s it for Supplier Functional Interface, Will talk about other Predefined Functional Interface in my next blog.

Happy Coding…!!!

Consumer and BiConsumer Functional Interface - JAVA 8


Consumer and BiConsumer Functional Interface


Consumer<T> is an in-built functional interface introduced in Java 8 in the java.util.function package. It can be used in all contexts where an object needs to be consumed, i.e. taken as input, and some operation is to be performed on the object without returning any result.
Common example of such an operation is printing where an object is taken as input to the printing function and the value of the object is printed.

The functional method of Consumer is accept(T t).
@FunctionalInterface
Public interface Consume<T, > { …}

Here is a simple source code of java.util.function.Consumer
package java.util.function;
    
import java.util.Objects;
    
@FunctionalInterface
public interface Function<T> {
    public void accept(T t);
  }

Where accept (T t) is an abstract method where T is the type of the input to the Function.

Example 1:

import java.util.function.Consumer;

public class ConsumerExample {

       public static void main(String[] args) {

             // Calling Consumer Functional Interface without using Lambda Expression
             SendNotification notification = new SendNotification();
             notification.accept("Abdul");

             // Using Lambda Expression
             Consumer<String> consumer = username -> System.out.println("Send mail notification to : " + username);
             consumer.accept("Waheed");
       }
}

class SendNotification implements Consumer<String> {

       @Override
       public void accept(String user) {
             System.out.println("Send mail notification to : " + user);
       }
}

Output:
Send mail notification to : Abdul
Send mail notification to : Waheed



Example 2:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample2 {

       public static void main(String[] args) {

             ConsumerExample2 consumerExample2 = new ConsumerExample2();

             Consumer<Student> consumer = student -> {
                    System.out.println("Name: " + student.getName());
                    System.out.println("Age: " + student.getAge());
                    System.out.println("================================");
             };

             List<Student> students = consumerExample2.populateStudentList();
             for (Student student : students) {
                    consumer.accept(student);
             }
       }

       public List<Student> populateStudentList() {
             List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
                           new Student("DummyUser", 20), new Student("Adam", 25));
             return studentList;
       }
}

class Student {
       private String name;
       private int age;

       public Student(String name, int age) {
             super();
             this.name = name;
             this.age = age;
       }

       public String getName() {
             return name;
       }

       public void setName(String name) {
             this.name = name;
       }

       public int getAge() {
             return age;
       }

       public void setAge(int age) {
             this.age = age;
       }

       public boolean equals(Object obj) {
             Student student = (Student) obj;
             if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
                    return true;
             } else {
                    return false;
             }
       }
}

Output:
Name: Abdul
Age: 31
================================
Name: Waheed
Age: 29
================================
Name: DummyUser
Age: 20
================================
Name: Adam
Age: 25
================================

Example 3:

In this example, I’ll use Predicate, Function and Consumer for better understanding. Below Program will print Student detail with its grade (Generate Grade based on marks) who marks are greater than 60%.

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Function;

/**
 * Use of Predicate, Function and Consumer Functional Interface in one class;
 *
 * It will print name of the student who has marks greater than 60% with its
 * GRADE.
 *
 * @author Abdul Waheed
 *
 */
public class ConsumerExample3 {

       public static void main(String[] args) {

             ConsumerExample3 consumerExample3 = new ConsumerExample3();

             Predicate<Stud> p1 = student -> student.getMarks() > 60;

             Function<Stud, String> f1 = student -> {
                    int marks = student.getMarks();

                    if (marks > 80) {
                           return "A";
                    } else if (marks > 70) {
                           return "B";
                    } else if (marks > 60) {
                           return "C";
                    } else {
                           return "E";
                    }
             };

             // Internally invoking Function interface
             Consumer<Stud> c1 = student -> {
                    System.out.println("Name: " + student.getName());
                    System.out.println("Marks: " + student.getMarks());
                    System.out.println("Grade: " + f1.apply(student));
                    System.out.println("================================");
             };

             List<Stud> students = consumerExample3.populateStudentList();
             for (Stud stud : students) {
                    if (p1.test(stud)) {
                           c1.accept(stud);
                    }
             }
       }

       public List<Stud> populateStudentList() {
             List<Stud> studentList = Arrays.asList(new Stud("Abdul", 31, 60), new Stud("Waheed", 29, 90),
                           new Stud("DummyUser", 20, 80), new Stud("Adam", 25, 47));
             return studentList;
       }
}

class Stud {
       private String name;
       private int age;
       private int marks;

       public Stud(String name, int age, int marks) {
             super();
             this.name = name;
             this.age = age;
             this.marks = marks;
       }

       public String getName() {
             return name;
       }

       public void setName(String name) {
             this.name = name;
       }

       public int getAge() {
             return age;
       }

       public void setAge(int age) {
             this.age = age;
       }

       public int getMarks() {
             return marks;
       }

       public void setMarks(int marks) {
             this.marks = marks;
       }

       public boolean equals(Object obj) {
             Student student = (Student) obj;
             if ((this.getName().equals(student.getName()) && this.getAge() == student.getAge())) {
                    return true;
             } else {
                    return false;
             }
       }
}

Output:

Name: Waheed
Marks: 90
Grade: A
================================
Name: DummyUser
Marks: 80
Grade: B
================================

  



Apart from accept (T t) method, Consumer also has only one default method.

Modifier and Type
Method and Description
default Consumer<T>
andThen(Consumer<? super T> after)
Returns a composed Consumer that performs, in sequence, this operation followed by the after operation.


We can use andThen(Consumer<? super T> after) for Consumer Chaining i.e. we can call multiple Consumer Function at the same time.

C1.andThen(C2).andThen(C3).accept(“Student);

Over here, first C1 will be called then C2 and then C3.

Let’s understand with an example where if a new student register to a website, then data should be updated to database and send welcome mail to User as well.


Example 3:

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerChainning {

       public static void main(String[] args) {

             ConsumerChainning chainning = new ConsumerChainning();

             Consumer<Student> addToDB = Student -> {
                    System.out.println("Open Database Connection");
                    System.out.println("Write Record to DB");
                    System.out.println("Name: " + Student.getName() + ", Age: " + Student.getAge());
                    System.out.println("Close Connection");
                    System.out.println("================================");
             };

             Consumer<Student> sendMail = Student -> {
                    System.out.println("Configure Mail Server");
                    System.out.println("Send Mail to user " + Student.getName());
                    System.out.println("================================\n");
             };

             List<Student> students = chainning.populateStudentList();
             for (Student student : students) {
                    addToDB.andThen(sendMail).accept(student);
             }
       }

       public List<Student> populateStudentList() {
             List<Student> studentList = Arrays.asList(new Student("Abdul", 31), new Student("Waheed", 29),
                           new Student("DummyUser", 20), new Student("Adam", 25));
             return studentList;
       }

}

Output:

Open Database Connection
Write Record to DB
Name: Abdul, Age: 31
Close Connection
================================
Configure Mail Server
Send Mail to user Abdul
================================

Open Database Connection
Write Record to DB
Name: Waheed, Age: 29
Close Connection
================================
Configure Mail Server
Send Mail to user Waheed
================================

Open Database Connection
Write Record to DB
Name: DummyUser, Age: 20
Close Connection
================================
Configure Mail Server
Send Mail to user DummyUser
================================

Open Database Connection
Write Record to DB
Name: Adam, Age: 25
Close Connection
================================
Configure Mail Server
Send Mail to user Adam
================================

 BiConsumer Functional Interface


It is very similar to Consumer Functional Interface. The only difference is just that it will accept two input arguments instead of one and will return nothing

@FunctionalInterface
public interface BiConsumer<T,U> {
            accept(T t, U u);
}


Let’s see an example

Example 4:

import java.util.function.BiConsumer;

public class BiConsumerExample {

       public static void main(String[] args) {

             BiConsumer<String, String> fullName = (fn, ln) -> System.out.println(fn.concat(" " + ln));

             fullName.accept("Abdul", "Waheed");
       }
}
 Output:
Abdul Waheed 

That’s it for Consumer and BiConsumer Functional Interface, Will talk about other Predefined Functional Interface in my next blog.

Happy Coding…!!!

How TOPT Works: Generating OTPs Without Internet Connection

Introduction Have you ever wondered how authentication apps like RSA Authenticator generate One-Time Passwords (OTPs) without requiring an i...