Saturday, June 2, 2012

String Permutations


import java.util.ArrayList;

public class StringPermutation {

public static ArrayList<String> PermutationFinder(String s) {

ArrayList<String> perm = new ArrayList<String>();

if (s == null) { // error case

    return null;

} else if (s.length() == 0)

{

    perm.add(""); // initial

    return perm;

}

char initial = s.charAt(0); // first character

String rem = s.substring(1); // Full string without first character

ArrayList<String> words = PermutationFinder(rem);

for (String str : words)

{

    for (int i = 0; i <= str.length(); i++)

    {

        perm.add(charinsert(str, initial, i));

    }

}

return perm;

}

public static String charinsert(String str, char c, int j) {

String begin = str.substring(0, j);

String end = str.substring(j);

return begin + c + end;

}

public static  void main(String[] args) {

    String s = "CODE";

ArrayList<String> value = PermutationFinder(s);

System.out.println("\nThe Permutations are : \n" + value);

}

}

Friday, June 1, 2012

Exceptions and return types in overriding.


import java.io.IOException;
import java.sql.*;
public class Test1 {
public Test4 myMetohd1() throws Exception
{
return null;
}

}

class Test2 extends Test1 {
public Test5  myMetohd1() throws SQLException, IOException
{
return null;
}
}

class Test3 extends Test1 {
public Test5 myMetohd1()
{
return null;
}
}

class Test4
{
}

class Test5 extends Test4
{
}

Friday, May 25, 2012

If a class is serializable but its superclass in not , what will be the state of the instance variables inherited from super class after deserialization?


The values of the instance variables inherited from superclass will be reset to the values they were given during the original construction of the object as the non-serializable super-class constructor will run.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SubSerialSuperNotSerial {

    public static void main(String [] args) {

        ChildSerializable c = new ChildSerializable();
        System.out.println("Before : - " + c.noOfWheels + " "+ c.color);
        try {
        FileOutputStream fs = new FileOutputStream("superNotSerail.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(c);
        os.close();
        } catch (Exception e) { e.printStackTrace(); }

        try {
        FileInputStream fis = new FileInputStream("superNotSerail.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        c = (ChildSerializable) ois.readObject();
        ois.close();
        } catch (Exception e) { e.printStackTrace(); }
        System.out.println("After :- " + c.noOfWheels + " "+ c.color);
        }

}

 class ParentNonSerializable {
    int noOfWheels;
   
    ParentNonSerializable(){
        this.noOfWheels = 4;
    }
   
}


 class ChildSerializable extends ParentNonSerializable implements Serializable {
 
    private static final long serialVersionUID = 1L;
    String color;


    ChildSerializable() {
        this.noOfWheels = 8;
        this.color = "blue";
    }
}



Result on executing above code –
Before : - 8 blue
After :- 4 blue
The instance variable ‘noOfWheels’ is inherited from superclass which is not serializable. Therefore while restoring it the non-serializable superclass constructor runs and its value is set to 8 and is not same as the value saved during serialization which is 4.

Tuesday, May 22, 2012

Thread pool:Concurrency

import java.util.ArrayList;
import java.util.List;

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ExecutorService;

public class Concurrency {

   public static void main(String args[]) {
       long start = System.currentTimeMillis();

       // initialize pool
       ExecutorService pool = Executors.newFixedThreadPool(3);

       // store futures somewhere
       List<Future<CallableData>> futures = new ArrayList<Future<CallableData>>();

       // submit a bunch of Callables to the Pool
       for(int i = 0; i < 10; i++) {
           System.out.println("Creating! " + i);
           futures.add(pool.submit(new CallableData(i)));
       }

       // wait for everything to finish
       for(Future<CallableData> future : futures) {
           try {
               CallableData data = future.get();
               System.out.println("Got result!" + data.getFoo());
           } catch (Exception e){
               e.printStackTrace();
           }
       }

       System.out.println("Total time: " + (System.currentTimeMillis() - start) + " ms");

       // don't forget to shutdown
       pool.shutdown();
   }

   private static class CallableData implements Callable<CallableData> {
       private int foo;
       public CallableData(int foo) {
           this.foo = foo;
       }
       public CallableData call() {
           System.out.println("Running! " + foo);
           try { Thread.sleep(2000); } catch (Exception e) {}
           foo = foo + 1000;
           System.out.println("Completed! " + foo);
           return this;
       }
       public int getFoo() {
           return foo;
       }
   }
}

Friday, May 18, 2012

Why HashSet / HashMap in java does not maintain the insertion order?


Why HashSet / HashMap in java does not maintain the insertion order? example code

Tough interview questions like "Why HashSet / HashMap in java does not maintain the insertion order? OR Why HashSet / HashMap does not make guarantee that the iteration order will remain constant over time?" may be asked .When you run the following code with default hash map capacity (16) , you may get the output as gvien below
    
import java.util.*;
import java.util.*;
class HashMap2
{
public static void main(String args[]) {
HashMap hm=new HashMap();
hm.put("545", "Kumar");
hm.put("5143", "Jegan");
hm.put("767", "Akshu");
hm.put("1766", "Lakshan");
    Iterator it = hm.entrySet().iterator();
System.out.println("\nIteration Order when using HashMap");
    while (it.hasNext()) {
        Map.Entry keyValue= (Map.Entry)it.next();
        System.out.println(keyValue.getKey() + " -> " + keyValue.getValue());
    }
HashSet<String> set = new HashSet<String>(16);
set.add("Apple");
set.add("Banana");
set.add("Orange");
set.add("Pine Apple");
System.out.println("\nIteration Order when using HashSet");
  for (String fruit : set){
         System.out.println(fruit); }
}
}


Insertion Order in HashMap : 545 , 5143, 767, 1766 . In HashSet : Apple, Banana, Orange, Pine Apple. The Iteration order is given below.
Output:

In the above output , the display order (iteration order) is different from the order in which the elements are inserted. Let us see how does this happen ?
HashSet stores elements in a hash table (actually through a HashMap instance , where element in the HashSet is the key to HashMap and dummy object is passed as a value). So the below answer is applicable to both HashMap and HashSet . Hashing determines where the object has to be placed in a HashMap. In Detail : HashMap internally uses an array to store key and value pairs (i.e the reference to HashMap.Entry objects where HashMap.Entry objects have the fields to store hash, key ,value , link to next HashMap.Entry object - a linked list implementation) . The index to above array is calculated from the key using hash function. The hash function accepts the hashcode of the key (key.hashCode()) and calculates the hash using formula given below and returns hash. The index is calculated based on the hash value and the length of array (Capacity) with the formula ( h & (length-1) , h -> hash value, length -> array capacity) so that the elements (key-value pairs) can be distributed in the array within the given range (capacity) . Array can be resized if required but the length should be a power of two. So whenever the length (capacity) of the array is resized to 2^n , the index of the element is also changed .Thus the iteration order is changed.
Function to calculate hash using the hashcode of key.
    
//fromJava Source code . This function ensures that hashCodes that differ only by constant multiples at each bit position have a bounded  number of collisions (approximately 8 at default load factor).
  static int hash(int h) {
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

The below code prints the index which is calculated using the hashcode and capacity using hash function .
    
import java.util.*;
class HashMap3
{
public static void main(String args[]) {
int length=128; // capacity
HashMap hm=new HashMap(length);
hm.put("545", "Kumar");
hm.put("5143", "Jegan");
hm.put("767", "Akshu");
hm.put("1766", "Lakshan");
    Iterator it = hm.entrySet().iterator();
System.out.println("\nIteration Order when using HashMap with capacity : "+ length);
    while (it.hasNext()) {
        Map.Entry keyValue= (Map.Entry)it.next();
        System.out.println(  "Index : " + (hash(keyValue.getKey().hashCode()) & (length -1) )+ " " +  keyValue.getKey() + " -> " + keyValue.getValue());
    }

HashSet<String> set = new HashSet<String>(length);
set.add("Apple");
set.add("Banana");
set.add("Orange");
set.add("Pine Apple");

System.out.println("\nIteration Order when using HashSet with capacity : "+ length);
    for (String fruit : set){
System.out.println("Index : " + (hash(fruit.hashCode()) & (length -1) )+ " Element : " + fruit);
}
}

static int hash(int h) {
         h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }
}

Output :

Two keys with different hashCode can also generate the same index (collisions) . In the above output, Orange and Banana has same index 12. The following two lines of code adds new elements and also solves collision.
Entry e = table[index];
table[index] = new Entry(hash, key, value, e);

if e==null means , there is no collision. Collision can be resolved by many techniques like Chaining

Picture : HashMap with Collision

Change the length to 128 and run the above program . The index / iteration order is changed.

Final conclusion : The location of the element in the HashMap is determined by the Hashcode of key and capacity of the HashMap.
Note: To maintain insertion order , you can use LinkedHashSet / LinkedHashMap

Tuesday, April 24, 2012

Test Object state after serialization and transient variables state.


import java.io.*;
public class TestSerializationVersion {

public static  void main(String [] args)
{
Dog d=new Dog(45,"Ramesh");

try
{
System.out.println(d.getName()+"    "+d.getAge());
//FileOutputStream fos=new FileOutputStream("Anand.txt");
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("Anand.txt"));
oos.writeObject(d);
d.setAge(56);
d.setName("Sravani");
System.out.println(d.getName()+"    "+d.getAge());
oos.close();
}
catch(IOException ex)
{
ex.printStackTrace();
}


try
{
//FileOutputStream fos=new FileOutputStream("Anand.txt");
ObjectInputStream ios=new ObjectInputStream(new FileInputStream("Anand.txt"));
Dog d1=(Dog)ios.readObject();
    ios.close();
System.out.println(d1.getName()+"    "+d1.getAge());
}
catch(ClassNotFoundException ex)
{
ex.printStackTrace();
}

catch(IOException ex)
{
ex.printStackTrace();
}

}
}


class Dog implements Serializable
{
private int age;
private transient String name;
public Dog(int age, String name)
{
this.age=age;
this.name=name;
}

public String getName()
{
return name;
}

public int getAge()
{
return age;
}

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

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

}

Thursday, April 19, 2012

Sequential run of threads

Thread t1 = new Thread( new MyRunnable( ) );
Thread t2 = new Thread( new MyRunnable( t1 ) );
Thread t3 = new Thread( new MyRunnable( t2 ) );
t1.start();
t2.start();
t3.start();

...

class MyRunnable()
{
   private Thread mustFinishFirst;
   public MyRunnable()
   {}
   public MyRunnable( Thread mustFinishFirst )
   {
      this.mustFinishFirst = mustFinishFirst;
   }
   public void run()
   {
      if( mustFinishFirst != null )
         mustFinishFirst.join()
      ...
   }
}