Tuesday, 30 August 2016

Thread - How to create thread in Java?

We learned the basics of threads, Thread Lifecycle and States in previous post. Now its time to create a thread and run it.

There are two ways to create a thread in Java.

  1. Extending Thread class.
  2. Implementing Runnable interface.
There are other ways also, like by using Callable interface. But in this article we will discuss the basic ways of thread creation. I will write separate articles for other specific ways of thread creation by callable or by using executor framework.

Create thread by extending Thread class - 
The most basic way to create a thread is by extending Thread class and overrides its run() method. Thread class in java extends Object class and implements Runnable interface.
Below is a sample code to create thread by extending Thread class.

package threads;

public class ThreadByExtending extends Thread {

    public void run() {
        System.out.println("ThreadByExtending is in running state.");
    }

    public static void main(String args[]) {
        ThreadByExtending thread = new ThreadByExtending();
        thread.start();
    }
}

Create thread by implementing Runnable interface
By implementing Runnable interface we create a runnable object that is passed to thread constructor for creating a new thread. Runnable interface has only one method run() that needs to be overridden. Below is a sample code to create thread by implementing Runnable interface.

package threads;

public class ThreadByImplementing implements Runnable {
    public void run() {
        System.out.println("ThreadByExtending is in running state.");
    }

    public static void main(String args[]) {
        ThreadByImplementing runnable = new ThreadByImplementing();
        Thread thread = new Thread(runnable);
        thread.start();
    }
}


Which way of Thread creation should be used -
Both ways of creating thread are good and can be used. But implementing Runnable interface is preferable because if we want to extend some other class also, then that can be extended with Runnable method only. 

Thread - Basics, Life Cycle & States

Threading is very important topic while talking about Java programming language. We will learn thread basics, thread states and thread life cycle in this post. First we will see some basic definitions.

Process 
In simple words a program in execution is a called process. Process have their own address space. Processes are referred as heavy weight activities/task, because context switching between processes is very expensive. In a process there can be multiple threads.

Thread
thread is an independent path of execution within a program/process. In a process multiple threads can run concurrently. Thread class in java controls the thread executions in java.Every thread in Java is created and controlled by the java.lang.Thread class.

Multi-threading
Running multiple tasks concurrently in a program is called multithreading.

Thread Lifecycle & Thread States
Thread execution in Java is controlled by java.lang.Thread class. Thread lifecycle starts with creation of thread object (new state) and ends on dead state of thread. Let's understand the thread states first - A thread mainly have four states (new, runnable, blocked and dead). But we will talk about one more state that is Running state.





  • New State - When a new thread object is created using new() operator, thread will be in new state. At this state thread is not alive.
  • Runnable State - When start() method of Thread class is called, thread moved to runnable state. In this state thread is picked up by scheduler for execution, but when the execution will start is totally depends on scheduling algorithm of the operating system.
  • Running State - Running state is the actual execution state of the thread where run() of the thread is called and statements written in run() method will be executed. From running state a thread can enter into blocked or dead state. 
  • Blocked State - When thread is waiting on some I/O or any other reason, it is said to be in blocked state. After blocked state thread can not go to for execution directly, it needs to wait for thread scheduler to pick up for execution.
  • Dead State - This is the final state of a thread. After completing execution thread enters into dead state.

This is all about thread life cycle. I will create a new post on ways of thread creation separately. 
I hope you will like this article. If you have any doubts please put in comments.

Check below links also-
Bubble Sort Algorithm analysis and implementation in Java
Linear Search Algorithm analysis and implementation in Java
Binary Search Algorithm analysis and implementation in Java
Java8 - Lambda Expressions in Java
Java8 - Default and static methods in Interface
How to create Immutable classes in JAVA

Java - Bubble Sort Algorithm

We have studied about searching algorithms Linear Search and Binary Search in previous post. Now I am starting a series of sorting algorithms. Sorting algorithm are used to sort a given array or collection in ascending or descending order according to the required order.

We will start with the simplest sorting algorithm - Bubble Sort. Bubble sort is good for very small size collections only. For bigger collections we have many other better algorithms available like Quick Sort and Merge Sort etc. I will write separate articles for all sorting algorithms.  

Bubble Sort -
Bubble sort is the simplest sorting algorithm. Bubble sort simply start a loop for all elements in the array and compare the adjacent pairs, If elements are in wrong order it just swap the elements and continue till the all elements comes in sorted order. 
Simple steps to perform bubble sort - 
  • Given : An array of n elements in unsorted order.
  • Required : An array of n elements in ascending order. 
  • Start a loop from i= 0 to n-1.
  • Start an inner loop from j=1 to n-i, compare each adjacent elements. If elements are not in ascending order swap them. On complete iteration last element in the array will be the biggest element.
  • Get the sorted array.
Pseudo code (Ascending order)- 
# Input: Array elements of length n in unsorted order
# Output: Array elements of length n in ascending order

    n = length(elements)
    for i=0 to n-1 
       for j = 1 to n-i
          if elements[j-1] > elements[j] then
             swap(elements[j-1], elements[j])
          end if
       End for loop.
    End while loop.


Asymptotic Analysis of Bubble Sort Algorithm -

Best Case Scenario - If the given array or collection is already in sorted order. Best case time complexity for bubble sort is O(n).

Worst Case Scenario - If the given array or collection in reversed sorted order.  Worst case time complexity for bubble sort is О(n2).

Complexity - Complexity of bubble sort algorithm is О(n2)

Bubble Sort Implementation in Java  -

package javaprinciples.dsa;

public class BubbleSort {

public static void main(String[] args) {
int elements[] = { 4, 12, 56, 2, 7, 123, 6, 78 };

System.out.print("Input unsorted array -");
for (int element : elements) {
System.out.print(element + " ");
}

bubbleSort(elements);
System.out.print("\nOutput sorted array -");
for (int element : elements) {
System.out.print(element + " ");
}
}

static void bubbleSort(int[] elements) {
int n = elements.length;
int temp = 0;
for (int i = 0; i < n; i++) {
for (int j = 1; j < (n - i); j++) {
if (elements[j - 1] > elements[j]) {
temp = elements[j - 1];
elements[j - 1] = elements[j];
elements[j] = temp;
}
}
}
}
}

Output -

Input unsorted array -4 12 56 2 7 123 6 78 
Output sorted array -2 4 6 7 12 56 78 123 

Note - This is the simplest implementation of bubble sort algorithm. Above implementation will always sort the collection with О(n2) complexity. This can be optimized to make it more faster by breaking the loop if array is sorted before completing all the loops. Try to optimize above program by yourself.

Difference between Comparable and Comparator in Java 

Monday, 29 August 2016

Java - Binary Search Algorithm

We studied about Linear Search Algorithm in previous post. Linear search don't required the list to be in sorted order. Linear search is a good options for small and unsorted collection. But If the collection size increases linear search is not the ideal search algorithm to use. Binary search is better option for larger collections. One thing required in binary search is the collection must be in sorted order.

Binary Search
Binary search works on divide ans conquer technique, where problem is divided in smaller parts and solved. In binary search the given collection must be in sorted order always. Steps to perform binary search on a given array A to search key are - 

  • Find the middle element of A and match with key. If key matches return the index as result.
  • If key is less than middle element take the first half otherwise take the second half and perform the same steps.
  • If array size reached to zero, return "Element not present in array".  
Binary search reduced the problem(Array) size to half with each step. That's why binary search works efficiently for larger size data also.

Binary search algorithm can be implemented in iterative or recursive manner. I am using iterative methods for this tutorial, you can try with recursive manner for your practice.

Pseudocode 
# Input: Array elements, Integer size, Integer keyToSearch
# Output: first index of keyToSearch in elements, or -1 if not found
   Set startIndex = 1
   Set endIndex = n
   while keyToSearch not found 
      if startIndex < endIndex 
         return -1.
      set midPoint = startIndex + ( endIndex - startIndex ) / 2
      if A[midPoint] < keyToSearch
         set startIndex = midPoint + 1
      if A[midPoint] > keyToSearch
         set endIndex = midPoint - 1 
      if A[midPoint] = keyToSearch 
         return midPoint.
   End while loop. 
   
Asymptotic Analysis of Binary Search Algorithm -

Best Case Scenario - If the required element is the middle element in the collection and found in first step. Best case time complexity for binary search is O(1).

Worst Case Scenario - If the required element not present in the collection or found in last iteration. Worst case time complexity for binary search is O(log n).

Complexity - Complexity of binary search algorithm is O(log N). The time taken by algorithm to search an element will increase in logarithmic manner with the number of elements in the list.

Binary Search Implementation(Iterative) in Java  -
package javaprinciples.dsa;

public class BinarySearch {

public static int binarySearch(int[] elements, int keyToSearch) {

int startIndex = 0;
int endIndex = elements.length - 1;
while (startIndex <= endIndex) {
int midPoint = startIndex + (endIndex - startIndex) / 2;
if (keyToSearch == elements[midPoint]) {
return midPoint;
}
if (keyToSearch < elements[midPoint]) {
endIndex = midPoint - 1;
} else {
startIndex = midPoint + 1;
}
}
return -1;
}

public static void main(String[] args) {
int[] elements = { 2, 3, 5, 6, 7, 8, 10, 12, 14 };
int keyToSearch = 8;
int keyFoundAt = binarySearch(elements, keyToSearch);
if (keyFoundAt == -1) {
System.out.println("Key " + keyToSearch + " not found in list.");
} else {
System.out.println("Key " + keyToSearch + " found at index: " + keyFoundAt);
}
}

}

Output -
Key 8 found at index: 5

This is all about Binary Search algorithm and its implementation in Java. I hope you liked the post. Feel free to put comments.

Java - Linear Search Algorithm

Linear Search
Linear search in a sequential search algorithm to search a particular element from a given list of elements. It starts from the first element in the list and check each element in sequence till the required element found or list ends. Linear search do not required the list or array to be in sorted order. 

Pseudocode -
# Input: Array elements, integer keyToSearch
# Output: first index of keyToSearch in elements, or -1 if not found
 For i = 0 to last index of elements:
   if elemnts[i] equals keyToSearch:
     return i

 return -1

Asymptotic Analysis of Linear Search Algorithm -

Best Case Scenario - Best case in linear search if the required element is found in first place. Best case time complexity is O(1).

Worst Case Scenario - Worst case in linear search if the element if last element in the list or element is not present in list. Worst case time complexity is O(N).

Complexity - Complexity of linear search algorithm is O(N). The time taken by algorithm to search an element will increase linearly with the number of elements in the list.

Linear Search Implementation in Java  -
package javaprinciples.dsa;

public class LinearSearch {

public static void main(String[] args) {
int[] elements = { 22, 45, 12, 32, 78, 56, 88 };
int keyToSearch = 12;
int keyFoundAt = linerSearch(elements, keyToSearch);
if (keyFoundAt == -1) {
System.out.println("Key " + keyToSearch + " not found in list.");
} else {
System.out.println("Key " + keyToSearch + " found at index: " + keyFoundAt);
}
}

public static int linerSearch(int[] elements, int keyToSearch) {
int size = elements.length;
for (int i = 0; i < size; i++) {
if (elements[i] == keyToSearch) {
return i;
}
}
return -1;
}

}

Output -
Key 12 found at index: 2


So this is all about linear search algorithm and its implementation in Java. I hope you will like it.

Friday, 26 August 2016

Java8 - Lambda Expressions

Lambda Expressions are Java8 new features. Lambda expressions are mainly used to implemented functional interfaces. We will try to understand
need and use of Lambda Expressions in this blog.

Why Lambda Expression -
We know that Java is an object oriented programming language, If we leave primitive variables than everything else in java is object based. 
But sometime we need to pass a function in a method. In functional programming we have a special feature called closure (closure is a function that can be stored as a variable - referred to as a "first-class function"), but in Java there is nothing like closure. To do the same in Java we use Anonymous class.
The problem with Anonymous classes are the complex syntax. For simple operation also we need to write additional syntactical code each time. The problem of bulky syntax is refereed as “Vertical problem” by Java people. So to bridge this gap between functional and OOP's programming Java introduced Lambda expressions, which are simply alternate of anonymous classes but only for the interfaces with single abstract methods (Functional Interfaces), in case of non functional interfaces we still need to use the anonymous class.

For example : consider the EventListener interface
button.addEventListener(new EventListener() {
   public void onEvent(Event e) {
      // code goes here .....
   }
});

For example - If we use anonymous class and we want to add above event code with more than one button, than we need to write the full code for each button(basically to avoid writing an implementation class for interface). Lambda Expressions also resolve this issue.

What is a Lambda Expression ?
In very simple words Lambda Expressions represent an anonymous function. Which can be passed as a parameter like an object and can be executed when required.

Type of a Lambda Expression will be of a some functional interface. We can store the Lambda Expression in a functional interface type and can execute it when required. This is basically solution of bulky anonymous implementation multiple times in a class.

Lambda Expressions introduced with a specific syntax. Basic syntax is -
(Argument List) -> (Function Body)

(int arg1, int arg2) -> {System.out.println("Passed arguments are - Frist: "+arg1+" Second: "+arg2)}

Let's understand all part of a Lambda Expression in detail.

Argument List

  • A lambda expression can have zero or more comma separated arguments in argument list.
  • Arguments in Lambda Expression can be passed with or without type, but you can not mix both together. Below given both are equal and valid Lambda expressions.
    (int arg1, int arg2) -> {System.out.println("Passed arguments
    are - Frist: "+arg1+" Second: "+arg2)}

    (arg1, arg2) -> {System.out.println("Passed arguments are - 
    Frist: "+arg1+" Second: "+arg2)}
  • "()" can be removed if there is only one argument in Lambda Expression.
    arg1 -> {System.out.println("Passed argument is : "+arg1)}

Function Body -
  • In Lambda Expression body there can be single or multiple statements.
  • If body contains only single statement, than it will be executed and result will be returned automatically.
         () -> {System.out.println("Nothing to print ...")}
  • If multiple statements are there in function body, it will execute all and add a return statement automatically on the basis of Functional Interface method return type. Or we can write return statement manually. 
         () -> {System.out.println("Nothing to print ...");
           System.out.println("Just to make multiline ...");}
  • If return statement is not written as last statement manually, java will try to put a return statement. So don't put any branching statement as last statement.  Below is a invalid lambda expression.
         () -> {System.out.println("Nothing to print ...");
           break;} //compile time error.

Now we can take a look of different valid Lambda expressions -

  1. () -> {System.out.println("Nothing to print ...")}
  2. arg1 -> {System.out.println("Passed argument is : "+arg1)}
  3. (arg1) -> {System.out.println("Passed argument is : "+arg1)}
  4. (String arg1) -> {System.out.println("Passed argument is : "+arg1)}
  5. (arg1, arg2) -> {System.out.println("Passed arguments
        are - Frist: "+arg1+" Second: "+arg2)}
  6. (int arg1, int arg2) -> {System.out.println("Passed arguments
        are - Frist: "+arg1+" Second: "+arg2)}
  7. () -> {System.out.println("Nothing to print ...");
               System.out.println("Just to make multiline ...");}
  8. () -> {System.out.println("Nothing to print ...");
               return "return is allowed";}
That's all about basics of Lambda Expressions, I hope now you have a good idea about Java8 Lambda Expressions. I will try to explain more new feature in my upcoming post. 

Wednesday, 24 August 2016

Java8 - Functional Interface

  • An interface which only declare one abstract methods is a functional interface. Interfaces with single abstract also called SAM (Single Abstract Method) interface.
  • @FunctionalInterface annotation can be used to declare an interface functional.
  • If we put more than one abstract method and @FunctionalInterface in a same interface, it will give a compile time error.
  • If we are not putting @FunctionalInterface annotation than also any interface with single abstract is a functional interface.
  • Other than a single abstract method, other methods like Default and static methods can be declared in functional interface.
  • If an functional interface override any Object class methods, than also it will be a valid functional interface. For example Comparator interface declared two methods compare()  and equals(), but its a functional interface because equals() method is overrided from Object class.
  • Major benefit of functional interface is that functional interfaces can be instantiated by Lambda Expressions, which are simple and short than anonymous classes. I will create a new post for Lambda Expressions separately. 

Example of valid functional interfaces -  
Example 1 -
@FunctionalInterface
public interface ValidFunctionalInterface1 {
public void abstractMethod1();
}

Example 2 -
@FunctionalInterface
public interface ValidFunctionalInterface2 {
public void abstractMethod1();
public void defaultMethod1(){
System.out.println("This is a default method..")
}
}

Example of invalid functional interfaces -

@FunctionalInterface
public interface InvalidFunctionalInterface1 {
public void abstractMethod1();
public void abstractMethod2();
}

Above interface will thow a compile time error, InvalidFunctionalInterface1 is not a functional interface.

Example of valid but not functional interface -

public interface InvalidFunctionalInterface1 {
public void abstractMethod1();
public void abstractMethod2();
}

I hope Functional Interfaces concept is clear now. If you have any doubts please put in comments below. 

Difference between Comparable and Comparator in Java

Tuesday, 23 August 2016

Java8 - Default & Static methods in interface

We have studied Interface many times, and as studied that we can declare methods in interface but can not provide implementation. So interface provides 100% abstraction.

But Java 8 was released with a lot of new features and improvements in existing API's.
New features introduced in Java 8 are Lambda Expression, Functional Interfaces, new Time API and new Stream API for bulk operations on collection classes. A lot of changes were introduced in existing API like Default and Static methods in interface, concurrent API changes and a lot other changes and improvement, but we will talk here for Interface changes only. I will create a separate article for Java8 features explanation.

Why Changes required in existing Interface -

As before Java8, method implementation in interface was not allowed. There are several reasons which were considered to make changes in java interface. Suppose we have an existing application and we are using interfaces. Now if we want to add some functionality in interface, it will break the whole application or we need to implement the new changes in all the places that interface is used.

For above reason abstract classes are used in as a default implementation class in many applications so we can add more functionalities in future.  One more important reason to introduce default and static method in interface is to support lambda expressions.

Default Method of Interface
A default method in interface can be defined using default keyword, and implementation class is not required to implement the default methods.

If two interfaces both have default method with same name are implemented by a class, than it is required to implement the default method in implementation class else it will throw an error. (This is required to prevent from Diamond problem with multiple inheritance in Java). 

Sample code for default method in interface - In below code sample It is not mandatory for implementing class to override the greeting(String name) methods. But if we want we can override this method.
public interface InterfaceWithDefaults {

 void method();
 
 default void greeting(String name){
  System.out.println("Hello "+name);
 }
}
Static Method of Interface -
Static methods of interface are same as default, the main difference between both is that we can not override static methods in implementation class.

Static methods are introduced for specific requirements, where we want to provide a default implementation for all the implementing classes that can not be changed.

Sample code for static method in interface - In below code sample implementing class can not override the greeting(String name) method. This static method will be available only in that particular interface. We can access the method as a static method with interface name like InterfaceWithStatic.greeting("Vijendra") .
public interface InterfaceWithStatic {

 void method();
 
 static void greeting(String name){
  System.out.println("Hello "+name);
 }
}

I hope Default and static method of interface are clear now. If you have any doubts please put in comments. I will try to resolve ASAP.

Difference between Comparable and Comparator in Java

                                                ***********************Keep studying***********************