Monday, June 13, 2016

LinkedList and ArrayList

Array List

Linked List
1) ArrayList implements it with a dynamically re-sizing array.

1)  LinkedList implements it with a doubly-linked list.
2) There is no descendingIterator() in ArrayList , so we need to write our own code to iterate over the ArrayList in reverse direction.

2) LinkedList can be iterated in reverse direction using descendingIterator()
3) If the constructor  is not overloaded , then ArrayList creates an empty list of initial capacity 10

3) LinkedList only constructs the empty list without any initial capacity.
4) In ArrayList each index only holds the actual object(data).
4) Memory overhead in LinkedList is more as LinkedList needs to maintain the addresses of next and previous node.
5) Performance

get(int index) is O(1) <--- main benefit of ArrayList<E>

add(E element) is O(1) amortized, but O(n) worst-case since the array must be resized and copied.

add(int index, E element) is O(n - index) amortized, but O(n) worst-case (as above)

remove(int index) is O(n - index) (i.e. removing last is O(1))

Iterator.remove() is O(n - index)

ListIterator.add(E element) is O(n - index)

5) Performance

get(int index) is O(n)
add(E element) is O(1)
add(int index, E element) is O(n)
remove(int index) is O(n)
Iterator.remove() is O(1) <--- main benefit of LinkedList<E>
ListIterator.add(E element) is O(1) <--- main benefit of LinkedList<E>


When to Use ArrayList and LinkedList :
In real world applications, you will more frequently use ArrayList than LinkedList. But in very specific situations LinkedList can be preferred.

1. ArrayList is preferred when there are more get(int) or search operations need to be performed as every search operation runtime is O(1).

2. If application requires more insert(int), delete(int) operations then the get(int) operations then LinkedList is preferred as they do not need to maintain back and forth like arraylist  to preserve continues indices.

public class ArrayLinkedList {

    public static void main(String[] args) {
           /*
            * transient Object[] elementData=                     DEFAULTCAPACITY_EMPTY_ELEMENTDATA; //
            * non-private to simplify nested class access private static final
            * Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
            * Constructs an empty list with an initial capacity of 10.
            */
           ArrayList arrayList = new ArrayList();
           arrayList.add("Life is Awesome");
           arrayList.add("Intern is a good movie");
          
           // Doubly LInked list implemented and not singly implemented
           LinkedList<String> linkedList = new LinkedList<String>();
           linkedList.add("Life is Awesome");
           linkedList.add("Intern is a beautiful movie");
         
           System.out.println("ArrayList is "+ arrayList);
           System.out.println("LinkedList is "+ linkedList);
    }
}

Output:

ArrayList is [Life is Awesome, Intern is a good movie]
LinkedList is [Life is Awesome, Intern is a beautiful movie]


Sunday, June 12, 2016

Intersection point of two linkedlist



public class LinkedListYShape {

     static Node head1, head2;

     public static void main(String[] args) {
           Node node1 = new Node(3);
           Node node2 = new Node(6);
           Node node3 = new Node(9);
           Node node4 = new Node(15);
           Node node5 = new Node(30);
           Node node6 = new Node(10);
           node1.setNextNode(node2);
           node2.setNextNode(node3);
           node3.setNextNode(node4);
           node4.setNextNode(node5);
           node6.setNextNode(node3);

           // Creating first and second Linked List
           LinkedListYShape list = new LinkedListYShape();
           list.head1 = node1;
           list.head2 = node6;
          
           // Approach 1-(Using difference of node counts)
           System.out.println("Intersection Node is " + list.getNode());
          
           // Approach 2-(Simply use two loops)
           System.out.println("Intersection Node is "+                 list._getIntersectionNodeUsingLoop(head1, head2));
     }

     int getNode() {
           int length1 = getCount(head1);
           int length2 = getCount(head2);
           int diff;
           if (length1 > length2) {
                diff = length1 - length2;
                return _getIntesectionNode(diff, head1, head2);
           } else {
                diff = length2 - length1;
                return _getIntesectionNode(diff, head2, head1);
           }

     }

     int _getIntesectionNode(int d, Node node1, Node node2) {
           int i;
           Node current1 = node1;
           Node current2 = node2;
           for (i = 0; i < d; i++) {
                if (current1 == null) {
                     return -1;
                }
                current1 = current1.getNextNode();
           }
           while (current1 != null && current2 != null) {
                if (current1.getData() == current2.getData()) {
                     return current1.getData();
                }
                current1 = current1.getNextNode();
                current2 = current2.getNextNode();
           }

           return -1;
     }

     int getCount(Node node) {
           Node current = node;
           int count = 0;
           while (current != null) {
                count++;
                current = current.getNextNode();
           }
           return count;
     }

     Node _getIntersectionNodeUsingLoop(Node head1, Node head2) {
          
           Node outerNode,innerNode;
           int length1=getCount(head1),length2=getCount(head2);
           if (length1 > length2) {
                outerNode = head1; innerNode = head2;
           } else {
                outerNode = head2; innerNode = head1;
           }
            
           while (outerNode != null) {
                while (innerNode != null) {
                     if (outerNode == innerNode)
                           return outerNode;
                     innerNode = innerNode.getNextNode();
                }
                innerNode=head2;
                outerNode = outerNode.getNextNode();
           }
           return innerNode;
     }
}

Output:
Intersection Node is 9
Intersection Node is 9


Monday, June 6, 2016

Class Loader in java

Applications written in statically compiled programming languages, such as C and C++, are compiled into native, machine-specific instructions and saved as an executable file. The process of combining the code into an executable native code is called linking - the merging of separately compiled code with shared library code to create an executable application. This is different in dynamically compiled programming languages such as Java. In Java, the .class files generated by the Java compiler remain as-is until loaded into the Java Virtual Machine (JVM) -- in other words, the linking process is performed by the JVM at runtime. Classes are loaded into the JVM on an 'as needed' basis. And when a loaded class depends on another class, then that class is loaded as well.
When a Java application is launched, the first class to run (or the entry point into the application) is the one with the public static void method called main(). This class usually has references to other classes, and all attempts to load the referenced classes are carried out by the class loader.
To get a feeling of this recursive class loading as well as the class loading idea in general, consider the following simple class:
public class ClassLoaderDemo {

     public static void main(String[] args) {
           System.out.println("Class Loaded successfully");
     }
}

C:\Users\admin\Desktop>java -verbose:class ClassLoaderDemo

[Loaded java.net.URLClassLoader$2 from C:\Program Files\Java\jre1.8.0_72\lib\rt.
jar]
[Loaded java.text.Format from C:\Program Files\Java\jre1.8.0_72\lib\rt.jar]
[Loaded java.text.MessageFormat from C:\Program Files\Java\jre1.8.0_72\lib\rt.ja
r]
[Loaded java.util.Locale$Category from C:\Program Files\Java\jre1.8.0_72\lib\rt.
jar]
[Loaded java.util.Locale$1 from C:\Program Files\Java\jre1.8.0_72\lib\rt.jar]
[Loaded java.text.FieldPosition from C:\Program Files\Java\jre1.8.0_72\lib\rt.ja
r]
[Loaded java.util.Date from C:\Program Files\Java\jre1.8.0_72\lib\rt.jar]
[Loaded java.text.AttributedCharacterIterator$Attribute from C:\Program Files\Ja
va\jre1.8.0_72\lib\rt.jar]
[Loaded java.text.Format$Field from C:\Program Files\Java\jre1.8.0_72\lib\rt.jar
]
[Loaded java.text.MessageFormat$Field from C:\Program Files\Java\jre1.8.0_72\lib
\rt.jar]
Error: Could not find or load main class ClassLoaderDemo
[Loaded java.lang.Shutdown from C:\Program Files\Java\jre1.8.0_72\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\Program Files\Java\jre1.8.0_72\lib\rt.ja
r]

When application class is loaded, all other classes required by application class must be loaded by JVM as “on demand basis”
The Java Classloader is a part of the JRE that dynamically loads Java classes into the JVM. Usually classes are only loaded on demand. The Java run time system does not need to know about files and file systems because of classloaders.

When the JVM is started, three class loaders are used:
ü  Bootstrap class loader
ü  Extensions class loader
ü  System class loader

Bootstrap class loader
It loads the core Java libraries located in the <JAVA_HOME>/jre/lib directory. This class loader, which is part of the core JVM, is written in native code.

Extensions class loader
The extensions class loader loads the code in the extensions directories (<JAVA_HOME>/jre/lib/ext or any other directory specified by the java.ext.dirs system property). It is implemented by the sun.misc.Launcher$ExtClassLoader class.

System class loader
It loads classes from the current classpath that can be set while invoking a program using -cp or -classpath command line options. This is implemented by the sun.misc.Launcher$AppClassLoader class.


Dynamic Class Loading
Loading a class dynamically is easy. All you need to do is to obtain a ClassLoader and call its loadClass()method. Here is an example:

public class MainClass {

       public static void main(String[] args) {

              ClassLoader classLoader = MainClass.class.getClassLoader();
              System.out.println("Class Loader is " + classLoader);

              try {
                     Class aClass = classLoader.loadClass("com.javadsalgo.MainClass");
                     System.out.println("MainClass.getName() = " + aClass.getName());
              } catch (ClassNotFoundException e) {
                     e.printStackTrace();
              }

       }
}

Output:

Class Loader is sun.misc.Launcher$AppClassLoader@18b4aac2
MainClass.getName() = com.javadsalgo.MainClass