Singleton Design Pattern | Implementation

Single Design Pattern is one of the creational style of design pattern. It is often used in scenarios where the class needs only one instance. One of the very common examples which we come across is the Database connection class, when we only need one connection to be shared among other Objects as creating multiple connections/separate connection for every other Object is a costly operation, which would slow down the operations.

How do you design a Singleton Class :

  • Make constructor as private
  • Write a static method which returns Object of same Singleton class. Here, the concept of Lazy initialization in used to write this static method.

How is Singleton Class different from Normal Class?

When instantiating a class, a normal class uses constructor where as a Singleton class will need a static method to create an instance of a class that too only if it is null i.e it is not already in use.

Different levels of making a class Singleton

Method 1: Classic Implementation also called lazy instantiation

class Singleton
{
    private static Singleton obj;
  
    // private constructor to force use of
    // getInstance() to create Singleton object
    private Singleton() {}
  
    public static Singleton getInstance()
    {
        if (obj==null)
            obj = new Singleton();
        return obj;
    }
}
            

Method 2: make getInstance() synchronized

// Thread Synchronized Java implementation of 
// singleton design pattern
class Singleton
{
    private static Singleton obj;
  
    private Singleton() {}
  
    // Only one thread can execute this at a time
    public static synchronized Singleton getInstance()
    {
        if (obj==null)
            obj = new Singleton();
        return obj;
    }
}
            

The main disadvantage of this is method is that using synchronized every time while creating the singleton object is expensive and may decrease the performance of your program

Method 3: Eager Instantiation

// Static initializer based Java implementation of
// singleton design pattern
class Singleton
{
    private static Singleton obj = new Singleton();
  
    private Singleton() {}
  
    public static Singleton getInstance()
    {
        return obj;
    }
}
            

Method 4 (Best): Use “Double Checked Locking”

// Double Checked Locking based Java implementation of
// singleton design pattern
class Singleton
{
    private volatile static Singleton obj;
  
    private Singleton() {}
  
    public static Singleton getInstance()
    {
        if (obj == null)
        {
            // To make thread safe
            synchronized (Singleton.class)
            {
                // check again as multiple threads
                // can reach above step
                if (obj==null)
                    obj = new Singleton();
            }
        }
        return obj;
    }
}              
            

Advantages of Singleton

Saves memory because object is not created at each request. Only single instance is reused again and again.

Summary

In this article we learnt about Singleton Design Pattern and its Implementation.
Hope you liked the article !


Java 8 – Optional

A new class Optional in java.util package used to represent a value is present or absent, its main purpose it to keep us away from too many null checks and NullPointerExceptions

Advantages of using Java 8 Optional :

  1. No more NullPointerException at run-time.
  2. Develop clean and neat APIs.
  3. No more Boiler plate code.
  4. Null checks are not required.

Various methods in Optional object

1. Code to retrieve the wrapped value using get API

Optional<String> opt = Optional.of("programmertoday");
String name = opt.get();

2. Basic Methods from Optional

Optional.ofNullable() method : returns a Non-empty Optional if a value present in the given object. Otherwise returns empty Optional.
Optional.empty() method : useful to create an empty Optional object.

import java.util.Optional;

public class OptionalBasicExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        String answer1 = "Yes";
        String answer2 = null;
        System.out.println("Non-Empty Optional:" + gender);
        System.out.println("Non-Empty Optional: Gender value : " + gender.get());
        System.out.println("Empty Optional: " + Optional.empty());
        System.out.println("ofNullable on Non-Empty Optional: " + Optional.ofNullable(answer1));
        System.out.println("ofNullable on Empty Optional: " + Optional.ofNullable(answer2));   // java.lang.NullPointerException   System.out.println("ofNullable on Non-Empty Optional: " +    Optional.of(answer2));     
       
        } }
        Output:
        Non - Empty Optional:
        Optional[MALE]
        Non - Empty Optional:
        Gender value :MALE
        Empty Optional:Optional.empty

        ofNullable on Non - Empty Optional:
        Optional[Yes]
        ofNullable on Empty Optional:Optional.empty

        Exception in thread "main" java.lang.NullPointerExceptio
        at java.util.Objects.requireNonNull(Objects.java:203)
        at java.util.Optional.<init> (Optional.java:96)
        at java.util.Optional.of(Optional.java:108)

3. Optional – map and flatMap methods

Optional.ofNullable() method returns a Non-empty Optional if a value present in the given object. Otherwise returns empty Optional.
Optionaal.empty() method is useful to create an empty Optional object.

import java.util.Optional;

public class OptionalMapFlatMapExample {
    public static void main(String[] args) {
        Optional<String> nonEmptyGender = Optional.of("male");
        Optional<String> emptyGender = Optional.empty();
        System.out.println("Non-Empty Optional:: " + nonEmptyGender.map(String::toUpperCase));
        System.out.println("Empty Optional    :: " + emptyGender.map(String::toUpperCase));
        Optional<Optional<String>> nonEmptyOtionalGender = Optional.of(Optional.of("male"));
        System.out.println("Optional value   :: " + nonEmptyOtionalGender);
        System.out.println("Optional.map     :: " + nonEmptyOtionalGender.map(gender -> gender.map(String::toUpperCase)));
        System.out.println("Optional.flatMap :: " + nonEmptyOtionalGender.flatMap(gender -> gender.map(String::toUpperCase)));
    }
}

Output:
        Non-Empty Optional::Optional[MALE]
        Empty Optional::Optional.empty
        Optional value::Optional[Optional[male]]
        Optional.map::Optional[Optional[MALE]]
        Optional.flatMap::Optional[MALE]

4. Optional – filter method

import java.util.Optional;

public class OptionalFilterExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        Optional<String> emptyGender = Optional.empty(); //Filter on Optional   
        System.out.println(gender.filter(g -> g.equals("male"))); //Optional.empty   
        System.out.println(gender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional[MALE]   
        System.out.println(emptyGender.filter(g -> g.equalsIgnoreCase("MALE"))); //Optional.empty   
        } 
}
        
Output:
        Optional.empty
        Optional[MALE]
        Optional.empty

5. Optional – isPresent and ifPresent methods

Optional.isPresent() returns true if the given Optional object is non-empty. Otherwise it returns false.
Optional.ifPresent() performs given action if the given Optional object is non-empty. Otherwise it returns false

import java.util.Optional;

public class OptionalIfPresentExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        Optional<String> emptyGender = Optional.empty();
        if (gender.isPresent()) {
            System.out.println("Value available.");
        } else {
            System.out.println("Value not available.");
        }
        gender.ifPresent(g -> System.out.println("In gender Option, value available."));   //condition failed, no output print   
        emptyGender.ifPresent(g -> System.out.println("In emptyGender Option, value available."));
    }
}

Output:
        Value available.
        In gender Option,value available.

6. Optional – orElse and orElseGet methods

It returns the value if present in Optional Container. Otherwise returns given default value.

import java.util.Optional;

public class OptionalOrElseExample {
    public static void main(String[] args) {
        Optional<String> gender = Optional.of("MALE");
        Optional<String> emptyGender = Optional.empty();
        System.out.println(gender.orElse("<N/A>")); //MALE   
        System.out.println(emptyGender.orElse("<N/A>")); //<N/A>   
        System.out.println(gender.orElseGet(() -> "<N/A>")); //MALE   
        System.out.println(emptyGender.orElseGet(() -> "<N/A>")); //<N/A>   
    }
}

Output:
        MALE
        <N/A>
        MALE
        <N /A>

Summary

In this article we learnt about Java 8 Optional package, its advantages and its variuos methods and implementations.
Hope you liked the article !


Java 8 – Lambdas

Lambda expressions or functions are nameless functions i.e just as anonymous function with no name.

Java earlier being only OOP language there was no existense of functions outside the object or instance. But since java 8 functional programming was introduced you can define functions, give them reference variables or pass them as method arguments and more.

Lambda syntax :

(x,y) -> x+y
1. (parameters) -> expression
2. (parameters) -> {statements;}
3. () -> expression

Some features of Lambda Expressions :

  1. A lambda expression can have zero, one or more parameters.
  2. When there is a single parameter, if its type is inferred, it is not mandatory to use parentheses. e.g. a -> return a*a.
  3. The body of the lambda expressions can contain zero, one or more statements. If body of lambda expression has single statement curly brackets are not mandatory and the return type of the anonymous function is the same as that of the body expression. When there is more than one statement in body than these must be enclosed in curly brackets.

Lambda relationship with Functional interfaces

SAM-Single Abstract Method Inferfaces also called as functional interfaces, java 8 enforces the rule of SAM by annotating these interfaces with a new annotation i.e @FunctionalInferface

        
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}        
      

If you try to add a new method in any functional interface, compiler would not allow you to do this and will throw compile time error.

So, How are they related ?

Let us see an example to find the relation, there is a thread which prints “Test Functional Interface”

        
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Test Functional Interface");
    }
}).start();
        
      

When we use lambda here , above code equivalent lambda is like this :

        
new Thread(
    () ->   {
                System.out.println("My Runnable run method");
            }
  ).start();
        
      

In simple words, a lambda expression is an instance of a functional interface.

Examples : Java 8 lambda expression

1. Iterating over a List and perform some operations

        
List<String> list = new ArrayList();
list.add("1");
list.add("2");
  
list.forEach(p ->  {
                    System.out.println(p);
                    //Do more work
                    }
                  );
        
      

2. Create a new runnable and pass it to thread

        
new Thread(
    () -> System.out.println("My Runnable");
).start();  
        
      

3. Sorting employees objects by their name

        
public class LambdaIntroduction {

public static void main (String[] ar){
  Employee[] employees  = {
      new Employee("David"),
      new Employee("Naveen"),
      new Employee("Alex"),
      new Employee("Richard")};
    
  System.out.println("Before Sorting Names: "+Arrays.toString(employees));
  Arrays.sort(employees, Employee::nameCompare);
  System.out.println("After Sorting Names "+Arrays.toString(employees));
        }
  }

class Employee {
  String name;
  
  Employee(String name) {
    this.name = name;
  }
  
  public static int nameCompare(Employee a1, Employee a2) {
    return a1.name.compareTo(a2.name);
  }
    
  public String toString() {
    return name;
  }
}
  
Output:
  
Before Sorting Names: [David, Naveen, Alex, Richard]
After Sorting Names [Alex, David, Naveen, Richard]  
        
      

Summary

In this article we learnt about Java 8 lambda expression, we learnt its syntax, its features, lambda with functional interface and its various other implementations with examples, try it out.
Hope you liked the article !


Java 8 – Functional Programming

Functional programming contains the following key concepts:

  • Functions as first class objects
  • Pure functions
  • Higher order functions

Pure functional programming has a set of rules to follow too:

  • No state
  • No side effects
  • Immutable variables
  • Favour recursion over looping

All the rules may not be applied at all times but you can still benefit by functional programming

Higher Order Functions

A function is a higher order function if at least one of the following conditions are met:
1. The function takes one or more functions as parameters.
2. The function returns another function as result.

      
public class HigherOrderFunctionClass {

  public <T> TestFactory<T> createTestFactory
    (IProducer<T> prod, IConfigurator<T> config) {
      
      return () -> {
          T obj = prod.produce();
          config.configure(obj);
          return obj;
      }
    }
  }
      >
    

Functional Interfaces

A functional interface in Java is an interface that only has one abstract method. By an abstract method is meant only one method which is not implemented. An interface can have multiple methods, e.g. default methods and static methods, both with implementations, but as long as the interface only has one method that is not implemented, the interface is considered a functional interface.

Example of a functional interface:

      
public interface MyInterface {
    public void run();
}
      
      

Here is another example of a functional interface with a default method and a static method too:

      
public interface MyInterface2 {
    public void run();

    public default void doIt() {
        System.out.println("doing it");
    }

    public static void doItStatically() {
        System.out.println("doing it statically");
    }
}
        
      

Notice the two methods with implementations. This is still a functional interface, because only run() is not implemented (abstract). However, if there were more methods without implementation, the interface would no longer be a functional interface, and could thus not be implemented by a Java lambda expression.

Summary

In this article we learnt about the Java 8 Functional Programming, Higher Order functions, functional interfaces and its examples.
Hope you liked the article !


Linkedlist

It is a linear data structure, unlike arrays it is not stored at contiguous location, the elements called nodes are linked using pointers, each pointer pointing to the next node.

Each node consists of mainly two part:

  • Data
  • Reference Link or address of next node and previous node

In java internally linkedlist is implemented using doubly linked list, in which we can add & remove elements from both sides of the list.

Features of LinkedList

  • Java LinkedList is an implementation of the List and Deque interfaces. It extends AbstractSequentialList and implements List and Deque interfaces.
  • It maintains the insertion order of the elements and also allow null elements.
  • In Java applications, we can use it as a List, stack or queue.
  • It does not support random access as it doesn’t implement RandomAccess Interface, so you cannot access elements randomly you have to access it sequentially(whereas Stack & ArrayList do implement this interface).
  • You can use ListIterator/Iterator to iterate LinkedList elements.

Different Ways to iterate over LinkedList

      
import java.util.LinkedList;
import java.util.Iterator;
public class ProgrammerTodayLinkedListExample{

  public static void main(String[] args) {

   LinkedList<String> list = new LinkedList<String>();
   list.add("welcome");
   list.add("to");
   list.add("LinkedList");
      
   System.out.println("*****Iterate Using Iterator*****");
   for (Iterator i = list.iterator(); i.hasNext();) {
     System.out.println(i.next());
   }
   
   System.out.println("*****Iterate Using ListIterator*****");
   ListIterator<String> listIterator = linkedList.listIterator();
   while (listIterator.hasNext()) {
     System.out.println(listIterator.next());
   }
   
   System.out.println("*****Iterate Using Traditional for loop*****");
   for (int i = 0; i < list .size(); i++) {
     System.out.println(list .get(i));
   }
    
   System.out.println("*****Iterate using Java8 forEach loop*****");
   // forEach Performs the given action for each element of the Iterable until 
   // all elements have been processed or the action throws an exception.
   linkedList.forEach(System.out::println); 
  }
}

OUTPUT

    
*****Iterate Using Iterator*****
welcome
to
LinkedList
*****Iterate Using ListIterator*****
welcome
to
LinkedList
*****Iterate Using Traditional for loop*****
welcome
to
LinkedList
*****Iterate using Java8 forEach loop*****
welcome
to
LinkedList    
    

LinkedList as Deque

Observe below in code block that on the left is the Deque Interface reference which creates a LinkedList object on the right. By this way linkedList can inherit Deque methods like addFirst(), addLast(), removeFirst(), removeLast(), etc methods.

    
import java.util.LinkedList;
import java.util.Deque;

public class LinkedListDequeExample 
{
  public static void main(String[] args) 
  {
  Deque<String> listDeque= new LinkedList<String>();
  listDeque.add(2);
  listDeque.addFirst(1);
  listDeque.addLast(3);
  listDeque.addFirst(0);
  listDeque.addLast(4);
      
  System.out.println("LinkedList contents : " + listDeque);
  System.out.println("LinkedList size : " + listDeque.size());
  listDeque.removeFirst();
  listDeque.removeLast();
  
  System.out.println("LinkedList contents : " + listDeque);
  System.out.println("LinkedList size : " + listDeque.size());	
  }
}

OUTPUT

      
  LinkedList contents : [0, 1, 2, 3, 4]
  LinkedList size : 5
  LinkedList contents : [1, 2, 3]
  LinkedList size : 3
  

LinkedList to Streams in Java 8

In java 8 use streams with forEach loop to iterate over the linkedlist.

    
List<Integer> ptlist= new LinkedList<>();
ptlist.add(11);
ptlist.add(22);
ptlist.add(33);
  
//Using stream to iterate through the List
ptlist.stream().forEach(System.out::println);
  

OUTPUT

    
11
22
33 
  

Difference between ArrayList and LinkedList | Usage

S.NoArrayListLinkedList
1Insertions & deletions are slowerInsertions & deletions are easy and fast in LinkedList because there is no resizing like arrays and then copying to another array if it gets full.
2Memory overhead is less as compared to LL as it stores only the dataMemory overhead is more as it stores both address and data
3Accessing an element in an array is fastwhile Linked list takes linear time(i.e have to start from the head), so it is quite a bit slower
4Arrays are of fixed sizeLinked lists are dynamic and flexible and can expand and contract its size
5In an array, memory is assigned during compile timewhile in a Linked list it is allocated during execution or runtime
4Arrays are of fixed sizeLinked lists are dynamic and flexible and can expand and contract its size

Example : Reverse a LinkedList without creating another one(without using additional space)

Algorithm:

  1. Create a linked list with n elements.
  2. Run the loop for n/2 times where ‘n’ is the number of elements in the linkedlist.
  3. In the first pass, Swap the first and nth element.
  4. In the second pass, Swap the second and (n-1)th element and so on till you reach the mid of the linked list.
  5. Return the linked list after loop termination.
      
import java.util.*; 

public class LinkedListTest2 { 
public static void main(String[] args) 
{ 
    // Declaring linkedlist without any initial size 
    LinkedList<Integer> linkedli = new LinkedList<Integer>(); 

    // Appending elements at the end of the list 
    linkedli.add(new Integer(1)); 
    linkedli.add(new Integer(2)); 
    linkedli.add(new Integer(3)); 
    linkedli.add(new Integer(4)); 
    linkedli.add(new Integer(5)); 
    System.out.print("Elements before reversing: " + linkedli); 

    // Calling user defined function for reversing 
    linkedli = reverseLinkedList(linkedli); // or use Collections.reverse(linkedli); 
    System.out.print("\nElements after reversing: " + linkedli); 
} 

// Takes a linkedlist as a parameter and returns a reversed linkedlist 
public static LinkedList<Integer> reverseLinkedList(LinkedList<Integer> llist) 
{ 
    for (int i = 0; i < llist.size() / 2; i++) { 
        Integer temp = llist.get(i); 
        llist.set(i, llist.get(llist.size() - i - 1)); 
        llist.set(llist.size() - i - 1, temp); 
    } 

    // Return the reversed arraylist 
    return llist; 
} 
} 

Time Complexity: O(n/2)
Space Complexity: O(1)

Output:

Elements before reversing: [1, 2, 3, 4, 5]
Elements after reversing: [5, 4, 3, 2, 1]

Good To Know – Internal working of LinkedList

Click “Internals of LinkedList” to Read More …