Search

Tuesday, May 30, 2017

ClassNotFoundException vs. NoClassDefFoundError

This is a very common question in Java interviews.
Here we will learn to distinguish between two similar, but different problems that can crop up in your code.

Similarities
ClassNotFoundException and NoClassDefFoundError occur when a particular class is not found at runtime. However, they occur at different scenarios.

Differences
ClassNotFoundException is an exception that occurs when you try to load a class at run time using Class.forName() or loadClass() methods and mentioned classes are not found in the classpath.
NoClassDefFoundError is an error that occurs when a particular class is present at compile time, but was missing at run time.

Let us see some examples

ClassNotFoundException

ClassNotFoundException is a runtime exception that is thrown when an application tries to load a class at runtime using the Class.forName() or loadClass() or findSystemClass() methods ,and the class with specified name are not found in the classpath. For example, you may have come across this exception when you try to connect to MySQL or Oracle databases and you have not updated the classpath with required JAR files. Most of the time, this exception occurs when you try to run an application without updating the classpath with required JAR files.

For example, the below program will throw ClassNotFoundException if the mentioned class "oracle.jdbc.driver.OracleDriver" is not found in the classpath.

public class CustomClassNotFoundException
{
    public static void main(String[] args)
    {
        try
        {
            Class.forName("oracle.jdbc.driver.OracleDriver");
        }catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}

If you run the above program without updating the classpath with required JAR files, you will get an exception like:

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at pack1.CustomClassNotFoundException.main(CustomClassNotFoundException.java:17)

NoClassDefFoundError

NoClassDefFoundError is an error that is thrown when the Java Runtime System tries to load the definition of a class, and that class definition is no longer available. The required class definition was present at compile time, but it was missing at runtime. For example, compile the program below.

class A
{
  // some code
}
public class B
{
    public static void main(String[] args)
    {
        A a = new A();
    }
}

When you compile the above program, two .class files will be generated. One is A.class and another one is B.class. If you remove the A.class file and run the B.class file, Java Runtime System will throw NoClassDefFoundError like below:

Exception in thread "main" java.lang.NoClassDefFoundError: A
at A.main(A.java:10)
Caused by: java.lang.ClassNotFoundException: A
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)

Recap

ClassNotFoundException
NoClassDefFoundError
It is an exception. It is of type java.lang.Exception.
It is an error. It is of type java.lang.Error.
It occurs when an application tries to load a class at run time which is not updated in the classpath.
It occurs when java runtime system doesn't find a class definition, which is present at compile time, but missing at run time.
It is thrown by the application itself. It is thrown by the methods like Class.forName(), loadClass() and findSystemClass().
It is thrown by the Java Runtime System.
It occurs when classpath is not updated with required JAR files.
It occurs when required class definition is missing at runtime.

Monday, May 29, 2017

How to Create a LinkList in Java

Today we will learn to create a custom LinkedList Program in Java which will have two basic operations - Adding a node and Deleting a node from the list.

We create a class LinkedNode having a int as value and a next pointer to point to next node in the list.

class LinkedNode {
    protected int value;
    protected LinkedNode next;
    public LinkedNode(int value) {
        this.value = value;
        this.next = null;
    }
   
}

We have a custom class LinkedList which have to three basic operations of a LinkedList -
(1) addNode() - Adding a node to the list
(2) deleteNode() - Deleting a node to the list.
(2) printList() - Printing LinkedList.

Here we are adding a node to the last node of the list.

Here is the full code in Java. We have a static variable head which always point to the head of the list -

public class LinkedList {

    static LinkedNode head =  null;
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        LinkedNode node = new LinkedNode(1);
        linkedList.addNode(node);
        LinkedNode node2 = new LinkedNode(2);
        linkedList.addNode(node2);
        LinkedNode node3 = new LinkedNode(3);
        linkedList.addNode(node3);
        System.out.println("After adding nodes, the list is -");
        linkedList.printList();
        linkedList.deleteNode(new LinkedNode(2));
        System.out.println("After deleting node 2 if present, the list is -");
        linkedList.printList();

    }

    private void deleteNode(LinkedNode node2) {
        if(head.value == node2.value){
            head = head.next;
            return;
        }else{
            LinkedNode temp1 = head;
            LinkedNode temp = head.next;
            while(temp != null && temp.value != node2.value ){
                temp1 = temp;
                temp = temp.next;
            }
            if(temp == null){
                System.out.println("The node to be delete is not found ");
            }else{
                temp1.next = temp.next;
            }
        }
    }

    private void printList() {
        if(head != null){
            LinkedNode temp = head;
            while(temp != null){
                System.out.print(temp.value + " ");
                temp = temp.next;
            }
            System.out.println();
        }else{
            System.out.println("The List is empty, Please add node elements first");
        }
       
       
    }

    private void addNode(LinkedNode node) {
        if(head == null){
            head = node;
            return;
        }
        else{
            LinkedNode temp = head;
            while(temp.next != null){
                temp = temp.next;
            }
            temp.next = node;
        }
    }

}

class LinkedNode {
    protected int value;
    protected LinkedNode next;
    public LinkedNode(int value) {
        this.value = value;
        this.next = null;
    }
   
}

Hope you like it. Please comment on any doubts.
Happy Learning !!!

Compare Two Arrays in Java

Compare Two Arrays in Java

Predict the output of following Java program.

class CompareArrays
{
    public static void main (String[] args)
    {
        int arr1[] = {1, 2, 3};
        int arr2[] = {1, 2, 3};
        if (arr1 == arr2) // Same as arr1.equals(arr2)
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}

Output : Not same

In Java, arrays are first class objects. In the above program, arr1 and arr2 are two references to two different objects. So when we compare arr1 and arr2, two reference variables are compared, therefore we get the output as "Not Same".

How to compare array contents?

A simple way is to run a loop and compare elements one by one. Java provides a direct method Arrays.equals() to compare two arrays. Actually, there is a list of equals() methods in Arrays class for different primitive types (int, char, ..etc) and one for Object type (which is base of all classes in Java).

// we need to import java.util.Arrays to use Arrays.equals().

import java.util.Arrays;
class CompareArrays
{
    public static void main (String[] args)
    {
        int arr1[] = {1, 2, 3};
        int arr2[] = {1, 2, 3};
        if (Arrays.equals(arr1, arr2))
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}

Output : Same

How to Deep compare array contents?

As seen above, the Arrays.equals() works fine and compares arrays contents. Now the questions, what if the arrays contain arrays inside them or some other references which refer to different object but have same values. For example, see the following program.

import java.util.Arrays;
class CompareArrays
{
    public static void main (String[] args)
    {
        // inarr1 and inarr2 have same values
        int inarr1[] = {1, 2, 3};
        int inarr2[] = {1, 2, 3};  
        Object[] arr1 = {inarr1};  // arr1 contains only one element
        Object[] arr2 = {inarr2};  // arr2 also contains only one element
        if (Arrays.equals(arr1, arr2))
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}

Output : Not Same

So Arrays.equals() is not able to do deep comparison. Java provides another method for this Arrays.deepEquals() which does deep comparison.

import java.util.Arrays;
class CompareArrays
{
    public static void main (String[] args)
    {
        int inarr1[] = {1, 2, 3};
        int inarr2[] = {1, 2, 3};
        Object[] arr1 = {inarr1};  // arr1 contains only one element
        Object[] arr2 = {inarr2};  // arr2 also contains only one element
        if (Arrays.deepEquals(arr1, arr2))
            System.out.println("Same");
        else
            System.out.println("Not same");
    }
}

Output : Same

How does Arrays.deepEquals() work?

It compares two objects using any custom equals() methods they may have (if they have an equals() method implemented other than Object.equals()). If not, this method will then proceed to compare the objects field by field, recursively. As each field is encountered, it will attempt to use the derived equals() if it exists, otherwise it will continue to recurse further.
This method works on a cyclic Object graph like this: A->B->C->A. It has cycle detection so ANY two objects can be compared, and it will never enter into an endless loop.

Exercise: Predict the output of following program

import java.util.Arrays;
class CompareArrays
{
   public static void main (String[] args)
   {
      int inarr1[] = {1, 2, 3};
      int inarr2[] = {1, 2, 3};
      Object[] arr1 = {inarr1};  // arr1 contains only one element
      Object[] arr2 = {inarr2};  // arr2 also contains only one element
      Object[] outarr1 = {arr1}; // outarr1 contains only one element
      Object[] outarr2 = {arr2}; // outarr2 also contains only one element       
      if (Arrays.deepEquals(outarr1, outarr2))
          System.out.println("Same");
      else
          System.out.println("Not same");
    }
}

Hope you like it. Let me know your comments. Happy Learning !!!

Friday, May 26, 2017

Difference Between String, StringBuilder And StringBuffer Classes in Java

Here we will explain the difference between String , StringBuilder and StringBuffer . As you will find that there are minor differences between the above mentioned classes.
String
  • String is immutable( once created cannot be changed ) object.
  • The object created as a String is stored in the Constant String Pool
  • Every immutable object in Java is thread safe, that implies String is also thread safe.
  • String cannot be used by two threads simultaneously.
  • String once assigned cannot be changed.
Example
String  demo = " hello " ;
// The above object is stored in constant string pool and its value cannot be modified.
demo = "Bye" ;     //new "Bye" string is created in constant pool and referenced by the demo variable 
// "hello" string still exists in string constant pool and its value is not overridden but we lost reference to the "hello" string
StringBuffer - StringBuffer is mutable means one can change the value of the object . - The object created through StringBuffer is stored in the heap . - StringBuffer has the same methods as the StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread safe .
Due to this it does not allow two threads to simultaneously access the same method. Each method can be accessed by one thread at a time.
But being thread safe has disadvantages too as the performance of the StringBuffer hits due to thread safe propert . Thus StringBuilder is faster than the StringBuffer when calling the same methods of each class.
String Buffer can be converted to the string by using toString() method.
Example:
StringBuffer demo1 = new StringBuffer("Hello") ;
// The above object stored in heap and its value can be changed.
demo1=new StringBuffer("Bye")
demo1=demo1.append("See You");
If you print demo1 you will get "HelloByeSee You"
StringBuilder - StringBuilder is same as the StringBuffer , i.e. the object is stored in heap and it can also be modified . - The main difference between the StringBuffer and StringBuilder is that StringBuilder is also not thread safe. It have all the methods of StringBuffer - StringBuilder is fast as it is not thread safe .


String
StringBuffer
StringBuilder
Storage
Constant String Pool
Heap
Heap
Mutable
No
Yes
Yes
Thread Safe
Yes
Yes
No
Performance
Fast
Slow
Fast

Hope you guys like it. Let me now in comments if you guys have any doubts. Happy Learning !!!

Reverse a String in less than O(n) time complexity and without using any loop

Here is a Java program which reverses a character array in < O(n) time complexity.
Here we are using recursion for reversing the characters. We traverse till the middle of the array to get the complete reverse array. Below is the Java code
ReverseString.java
import java.util.Arrays;

public class ReverseString {

    private static int size = 0;
    private static int length = 0;
    public static void main(String[] args) {

        char[] a = {'s','h','i','m','p','u'};
        length = a.length;
        System.out.println("Original String is : " + Arrays.toString(a));
        if(length > 1){
            a = reverse(a,0);
        }
        System.out.println("String after reversal : " + Arrays.toString(a));
    }

    private static char[] reverse(char[] a, int index) {

        if(size == a.length/2){
            return a;
        }
        char temp = a[index];
        a[index] = a[length-1];
        a[length-1] = temp;
        length--;
        size++;
        return reverse(a, index+1);
    }
}

Thursday, May 25, 2017

How to use "." as delimiter in String.split() method

String.split takes a regex, and '.' has a special meaning for regexes.
You have to use "\" along with "." in arguments like below
String[] words = line.split("\\.");
Some folks seem to be having trouble getting this to work, so here is some runnable code you can use to verify correct behaviour.
TestSplit.java
import java.util.Arrays;

public class TestSplit {
  public static void main(String[] args) {
    String line = "aa.bb.cc.dd";
    String[] words = line.split("\\.");
    System.out.println(Arrays.toString(words));
    // Output is "[aa, bb, cc, dd]"
  }
}

Wednesday, May 24, 2017

Convert a String to a Number without using Integer.parseInt() method

Here is a way to convert a input String to a Number without using inbuilt Integer.parseInt() method.
import java.util.Scanner;


public class ConvertStringToNumber {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the String to convert into a number");
        String original = sc.next();
        int number = convertToNumber(original);
        if(number ==  -1){
            System.out.println("Not a number. Please enter a valid number");
        }
        System.out.println("After converting the Number is : " + number);

    }

    private static int convertToNumber(String original) {
        int length = original.length();
        int number = 0;
        int tempNumber;
        int multiply = 1;
        while(length > 0){
            tempNumber = original.charAt(length-1) - '0';
            if(tempNumber > 9 || tempNumber < 0){
                return -1;
            }
            number = number + tempNumber * multiply;
            multiply *= 10;
            length--;
        }
        return number;
    }

}
Hope you guys like it. Happy Learning !!!

Java Palindrome Program

Below is a simple and an efficient way for checking whether an input string is Palindrome or not
import java.util.Scanner;

public class Palindrome {

    public static void main(String [] args){

        System.out.println("Enter the string for palindrome check : ");
        Scanner sc = new Scanner(System.in);
        String original = sc.next();
        boolean isPalindrome = isPalindrome(original);
        if(isPalindrome){
            System.out.println("The input string " + original + " is a palindrome");
        }else{
            System.out.println("The input string " + original + " is not a palindrome");
        }

    }

    public static boolean isPalindrome(String original){
        int length = original.length();
        int i = 0;
        while(length > 0){
            if(original.charAt(i) != original.charAt(length -1)){
                return false;
            }
            i++;
            length--; 
        }
        return true;
    }
}
Hope you like it !!

Tuesday, May 23, 2017

Java How to loop an Array

In this article, we will show you a few ways to print a Java Array.

1. Arrays.toString

This is the simplest way to print an Array – Arrays.toString (since JDK 1.5)
PrintArray.java
package com.javakernel.utils.print;

import java.util.Arrays;

public class PrintArray {

    public static void main(String[] args) {

  // array
        String[] arrayStr = new String[]{"Java", "Node", "Python", "Ruby"};
        System.out.println(Arrays.toString(arrayStr));
        // Output : [Java, Node, Python, Ruby]

  int[] arrayInt = {1, 3, 5, 7, 9};
        System.out.println(Arrays.toString(arrayInt));
        // Output : [1, 3, 5, 7, 9]

        // 2d array, need Arrays.deepToString
        String[][] deepArrayStr = new String[][]{{"mkyong1", "mkyong2"}, {"mkyong3", "mkyong4"}};
        System.out.println(Arrays.toString(deepArrayStr));
        // Output : [[Ljava.lang.String;@23fc625e, [Ljava.lang.String;@3f99bd52]

        System.out.println(Arrays.deepToString(deepArrayStr));
        // Output : [[mkyong1, mkyong2], [mkyong3, mkyong4]

        int[][] deepArrayInt = new int[][]{{1, 3, 5, 7, 9}, {2, 4, 6, 8, 10}};
        System.out.println(Arrays.toString(deepArrayInt));
        // Output : [[I@3a71f4dd, [I@7adf9f5f]

        System.out.println(Arrays.deepToString(deepArrayInt));
        // Output : [[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]

    }

}
Output
[Java, Node, Python, Ruby]
[1, 3, 5, 7, 9]
[[Ljava.lang.String;@23fc625e, [Ljava.lang.String;@3f99bd52]
[[mkyong1, mkyong2], [mkyong3, mkyong4]]
[[I@3a71f4dd, [I@7adf9f5f]
[[1, 3, 5, 7, 9], [2, 4, 6, 8, 10]]

2. JDK 8 Stream

In JDK 8, we can convert it to Stream and print it.
PrintArray.java
package com.javakernel.utils.print;

import java.util.Arrays;

public class PrintArray {

    public static void main(String[] args) {

        // array
        String[] arrayStr = new String[]{"Java", "Node", "Python", "Ruby"};
        Arrays.stream(arrayStr).forEach(System.out::println);

        int[] arrayInt = {1, 3, 5, 7, 9};
        Arrays.stream(arrayInt).forEach(System.out::println);

        //2d array
        String[][] deepArrayStr = new String[][]{{"mkyong1", "mkyong2"}, {"mkyong3", "mkyong4"}};
        Arrays.stream(deepArrayStr).flatMap(x -> Arrays.stream(x)).forEach(System.out::println);

        int[][] deepArrayInt = new int[][]{{1, 3, 5, 7, 9}, {2, 4, 6, 8, 10}};
        Arrays.stream(deepArrayInt).flatMapToInt(x -> Arrays.stream(x)).forEach(System.out::println);

    }

}
Output
Java
Node
Python
Ruby
1
3
5
7
9
mkyong1
mkyong2
mkyong3
mkyong4
1
3
5
7
9
2
4
6
8
10

3. Json Anything

This is my favor method, use Jackson2 library to print anything in a JSON formatted string.
PrintUtils.java
package com.javakernel.utils.print;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class PrintUtils {

    private static final ObjectMapper om = new ObjectMapper();

 public static void print(Object object) {
  String result;
  try {
   result = om.writerWithDefaultPrettyPrinter().writeValueAsString(object);
            System.out.println(result);
        } catch (JsonProcessingException e) {
   e.printStackTrace();
  }
 }

}
PrintArray.java
package com.mkyong.utils.print;

public class PrintArray {

    public static void main(String[] args) {

  //array
        String[] arrayStr = new String[]{"Java", "Node", "Python", "Ruby"};
        PrintUtils.print(arrayStr);

        int[] arrayInt = {1, 3, 5, 7, 9};
        PrintUtils.print(arrayInt);

  //2d array
        String[][] deepArrayStr = new String[][]{{"mkyong1", "mkyong2"}, {"mkyong3", "mkyong4"}};
        PrintUtils.print(deepArrayStr);

        int[][] deepArrayInt = new int[][]{{1, 3, 5, 7, 9}, {2, 4, 6, 8, 10}};
        PrintUtils.print(deepArrayInt);

    }

}
Output
[ "Java", "Node", "Python", "Ruby" ]
[ 1, 3, 5, 7, 9 ]
[ [ "mkyong1", "mkyong2" ], [ "mkyong3", "mkyong4" ] ]
[ [ 1, 3, 5, 7, 9 ], [ 2, 4, 6, 8, 10 ] ]

References

  1. Steam Javasoc
  2. Arrays JavaDoc
  3. Jackson 2 convert Java object to from JSON
  4. Jackson 2 official site

Featured Post

ClassNotFoundException vs. NoClassDefFoundError

This is a very common question in Java interviews. Here we will learn to distinguish between two similar, but different problems that ca...