IT Certificaions

Google Cloud Platform

Monday, October 31, 2011

SCJP 6 Questions: Pass by reference with example

See the code:


class GFC304 {
  static void m1(int[] i1, int[] i2) {
    int[] i3 = i1; 
 i1 = i2; 
 i2 = i3;
  }
  public static void main (String[] args) {
    int[] i1 = {1}, i2 = {3}; 
 m1(i1, i2);
    System.out.print(i1[0] + "," + i2[0]);
}}

What will be the output?

Answer: 1,3

Explanation: Here we are passing the copy of reference variables 
i1 and i2 from main() method to method m1(). Now m1 has it's own 
local reference variables i1 and i2 referring to same array as main()
method's i1 and i2. So you can see that we are only passing the 
reference variables not exactly the value they are refering.

See this figure...

Now see the second code.......

class GFC305 {
  static void m1(int[] i1, int[] i2) {
    int i = i1[0]; i1[0] = i2[0]; i2[0] = i;
  }
  public static void main (String[] args) {
    int[] i1 = {1}, i2 = {3}; m1(i1, i2);
    System.out.print(i1[0] + "," + i2[0]);
}}

What will be the output?

Answer: 3,1 

Explanation: Here in the m1() method we are passing the exact reference
containing array (i[0] and i2[0]) not the copy of reference variable(i1,i2).
See the figure...






Sunday, October 23, 2011

SCJP 6 Questions: Widening, autoboxing and varargs in overloading


The code is given:

3.  public class Bertha {
4.    static String s = "";
5.    public static void main(String[] args) {
6.        int x = 4; Boolean y = true; short[] sa = {1,2,3};
7.        doStuff(x, y);
8.        doStuff(x);
9.        doStuff(sa, sa);
10.       System.out.println(s);
11.   }
12.   static void doStuff(Object o) { s += "1"; }
13.   static void doStuff(Object... o) { s += "2"; }
14.   static void doStuff(Integer... i) { s += "3"; }
15.   static void doStuff(Long L) { s += "4"; }
16. }

What is the result?
A. 212
B. 232
C. 234
D. 312
E. 332
F. 334
G. Compilation fails

Answer:  A is correct. 

Explanation: It's legal to autobox and then widen. The first call to doStuff(), x is boxed from int to an Integer then passes these two objects (Integer,Boolean) to varargs (Object.... 0).

The second call cannot widen and then box (making the Long method unusable), so it boxes the int to an Integer. And then it goes to doStuff(Object o) because Integer is-A Object. As always, a
var-args method will be chosen only if no non-var-arg method is possible.

The third call is passing two objects—they are of type 'short array.'


1) Widening beats boxing
2) Widening beats var-args
3) Boxing beats var-args

Now see the rules for overloading methods using widening,boxing and varargs...

1) Primitive widening uses the "smallest" method argument possible.
2) Used individually, boxing and var-args are compatible with overloading.
3) You CANNOT widen from one wrapper type to another. (IS-A fails.)
4) You CANNOT widen and then box. (An int can't become a Long.)
5) You can box and then widen. (An int can become an Object, via Integer.)
6) You can combine var-args with either widening or boxing


Overloading with widening, boxing and Varargs


Overloading with Boxing and Var-args

class AddBoxing {
  static void go(Integer x) { System.out.println("Integer"); }  
  public static void main(String [] args) {
     int i = 5;
     go(i); 
  }
}

Answer: Integer


class AddBoxing { 
  static void go(long x) { System.out.println("long"); }
  public static void main(String [] args) {
     int i = 5;
     go(i); 
  }
}

Answer: long

Now see...

class AddBoxing {
  static void go(Integer x) { System.out.println("Integer"); }
  static void go(long x) { System.out.println("long"); }
  public static void main(String [] args) {
     int i = 5;
     go(i); // which go() will be invoked?
  }
}

If it is given that both methods exist, which one will be used? In other words, does the compiler think that widening a primitive
parameter is more desirable than performing an autoboxing operation?
The answer is that the compiler will choose widening over boxing, so the output will be

long


The compiler will choose the older style before it chooses the newer style, keeping existing code more robust. So far we've seen that

1) Widening beats boxing
2) Widening beats var-args

class BoxOrVararg {
  static void go(Byte x, Byte y){ System.out.println("Byte, Byte"); }
  static void go(byte... x) { System.out.println("byte... "); }
  public static void main(String [] args) {
      byte b = 5;
      go(b,b);  // which go() will be invoked?
  }
}

As it turns out, the output is
Byte, Byte

Just remember that the var-args method is like a "looser" than the other method, in that it could handle invocations with any number of
byte parameters. A var-args method is more like a catch-all method, in terms of what invocations it can handle.
--------------------------------------------------------

Widening Reference Variables

class Car {static void drive() { } }

class BMW extends Car {
    public static void main(String[] args) {
        Car d = new Car();
        d.show(d);   // is this legal ?
    }
    void show(Car a) { }
}

Yes, no problem, The show() method needs an Car refernece, and BMW IS-A Car. You just remember, the show() method thinks it's getting an Car object, so it will only
ask it to do Car things, which of course anything that inherits from Car can do.
So, here the compiler widens the BMW reference to an Car, and the invocation succeeds.

The key point here is that reference widening depends on inheritance or we can say that the IS-A test. Because of this, it's not legal to widen
from one wrapper class to another, because the wrapper classes are peers to one another. For instance, it's NOT valid to say that Short IS-A Integer.

See...
class Vehical {
  public static void main(String [] args) {
     Vehical d = new Vehical();
     d.test(new Integer(5));  // can't widen an Integer to a Long
   }
   void test(Long x) { }
}

Here compilation will fails as it can not widen Integer to Long.

---------------------------------------------------------------
Overloading When Combining Widening and Boxing

class WidenAndBox {
  static void go(Long x) { System.out.println("Long"); }
  public static void main(String [] args) {
    byte b = 5;
    go(b); // must widen then box - illegal
  }
}

This is just too much for the compiler:
WidenAndBox.java:6: go(java.lang.Long) in WidenAndBox cannot be
applied to (byte)

class BoxAndWiden {
    static void go(Object o) {
        Byte b2 = (Byte) o; // ok - it's a Byte object
        System.out.println(b2);
     } 
     public static void main(String [] args) {
        byte b = 5;
        go(b); // can this byte turn into an Object ?
     }
 }

This compiles (!), and produces the output:
5

Here what happened:
1) First the byte b was boxed to Byte object
2) Now the Byte Object widened to Object because Byte is-A Object (Byte extends Object)
3) And then we have type cast Object o to Byte and then print

But in previous code we were passing byte b to method go(Long x), where is-A test failed. So compiler generates error.

--------------------------------------------------------

Overloading in Combination with Var-args'

class VarargDemo {
   static void wide_vararg1(long... x){ System.out.println("long..."); }
   static void box_vararg2(Integer... x){ System.out.println("Integer..."); }
   public static void main(String [] args) {
      int i = 5;
      wide_vararg1(i,i); // needs to widen and use var-args
      box_vararg2(i,i); // needs to box and use var-args
   }
}

This compiles and produces:
long...
Integer...

This seems easy.

Now see the rules for overloading methods using widening,boxing and varargs...

1) Primitive widening uses the "smallest" method argument possible.
2) Used individually, boxing and var-args are compatible with overloading.
3) You CANNOT widen from one wrapper type to another. (IS-A fails.)
4) You CANNOT widen and then box. (An int can't become a Long.)
5) You can box and then widen. (An int can become an Object, via Integer.)
6) You can combine var-args with either widening or boxing


SCJP 6 Questions: Garbage collection

Qu1. See the code ...

3.   class Dozens {
4.      int[] dz = {1,2,3,4,5,6,7,8,9,10,11,12};
5.   }
6.   public class Eggs {
7.         public static void main(String[] args) {
8.               Dozens [] da = new Dozens[3];
9.               da[0] = new Dozens();
10.             Dozens d = new Dozens();
11.             da[1] = d;
12.             d = null;
13.             da[1] = null;
14.            // more code
15.       }
16.  }

Which two are true about the objects created within main(), and eligible for garbage collection
when line 14 is reached?

A. Three objects were created
B. Four objects were created
C. Five objects were created
D. Zero objects are eligible for GC
E. One object is eligible for GC
F. Two objects are eligible for GC
G. Three objects are eligible for GC

Answer:  C and F are correct. 

Explanation: When you compile and run,  main method from Eggs runs and object creation starts from line 8. It is first object which is a 1 D array object created.

Now at line 9, Dozens() class no-arg constructor calls and two objects created,
(i) first Class Dozens object  and (ii) integer array type referenced by dz

Similarly at Line 10, you again called new Dozens(), so again there will be two objects like line 9.

Hence total objects created:  Five

Now come to line 11, where you are refering da[1] to the obhect of type Dozen which is already refered by d.

so when you set d=null , da[1] still refer to same object. And finally at Line 13 when you do da[1]=null, here  second Dozens object (and its "int array" object) are not reachable.

So objects eligible for garbage collection: two 

See the figure....

Saturday, October 22, 2011

Interview Question @ IBM: Write your own generic class

Qu1: Can you write a small generic class by yourself ?

Answer: This could be like this......


public class GenericClassDemo<X, Y> {
   X name;
   Y age;


   GenericClassDemo(X name, Y age) {
      this.name = name;
      this.age = age;
   }


   X getX() { return name; }


   Y getY() { return age; }


   // test it by creating it with <String, Integer>


  public static void main (String[] args) {


       GenericClassDemo<String, Integer> obj= 
                     new GenericClassDemo<String, Integer>("Rajesh Kumar", 15);


       String empName = obj.getX();    // returns a String


       int empAge = obj.getY();    // returns Integer, unboxes to int


       System.out.println("Generic use::: EmpName  :"+empName +" and EmpAge :"+empAge);
}
}
----------------------------------------------------------------------------
Qu2. Create your own custom generic class using wildcard ?

Answer: Let's take an example..
---------------------------------------

abstract class Animal {
   public abstract void eat();
}


class Dog extends Animal {
  public void eat() { // implement Dog-specific code
    System.out.println("Dog is eating....");
  }
}


class Cat extends Animal {
  public void eat() { // implement Cat-specific code
     System.out.println("Cat is eat....");
  }
}








public class AnimalGenericTest<T extends Animal> {
   T animal;


   AnimalGenericTest(T animal){
     this.animal=animal;


   }   
   


   T getT(){
       return animal;
   }




   public static void main(String[] args) {
   
      AnimalGenericTest<Dog> dog = new AnimalGenericTest<Dog>(new Dog()); // OK
      AnimalGenericTest<Cat> cat = new AnimalGenericTest<Cat>(new Cat()); // OK


     // AnimalGenericTest<Integer> x = new AnimalGenericTest<Integer>(); // NO! Will not compile, 
      // because it takes only Animal of subclass of animal type object not Integer
      
      dog.getT().eat();
      cat.getT().eat();


       System.out.println("End of class........");
    }
}

--------------------------------------------------
The output will be as..........


C:\SCJP6\generics>javac AnimalGenericTest.java


C:\SCJP6\generics>java AnimalGenericTest
Dog is eating....
Cat is eat....
End of class........

----------------------------------------------------------
Qu3. How will you use generic method in this code??

See the code again:


import java.util.*;

abstract class Animal {
   public abstract void eat();
}


class Dog extends Animal {
  public void eat() { // implement Dog-specific code
    System.out.println("Dog is eating....");
  }
}


class Cat extends Animal {
  public void eat() { // implement Cat-specific code
     System.out.println("Cat is eat....");
  }
}








public class AnimalGenericTest<T extends Animal> {
   T animal;


   AnimalGenericTest(T animal){
     this.animal=animal;


   }   
   


   T getT(){
       return animal;
   }




   public <T> void makeArrayList(T t) { // take an object of an
      // unknown type and use a "T" to represent the type
      
      List<T> list = new ArrayList<T>(); // now we can create the list using "T"
      list.add(t);
      System.out.println("List is:"+list.toString());
   }


   public static void main(String[] args) {
   
      AnimalGenericTest<Dog> dog = new AnimalGenericTest<Dog>(new Dog()); // OK
      AnimalGenericTest<Cat> cat = new AnimalGenericTest<Cat>(new Cat()); // OK


     // AnimalGenericTest<Integer> x = new AnimalGenericTest<Integer>(); // NO! Will not compile, 
      // because it takes only Animal of subclass of animal type object not Integer
      
      dog.getT().eat();
      cat.getT().eat();
      
      dog.makeArrayList(dog.getT());


      cat.makeArrayList(cat.getT());


       System.out.println("End of class........");
    }
}
------------------------------------------------------------------------------

See the output:


C:\SCJP6\generics>javac AnimalGenericTest.java


C:\SCJP6\generics>java AnimalGenericTest
Dog is eating....
Cat is eat....
List is:[Dog@42e816]
List is:[Cat@9304b1]
End of class........


Ploymorphism with Generics in Java 5 or later



Ploymorphism with Generics

Generic collections give us sane advantages of type safety that we have always had with arrays, but there are some crucial differences

Most of these have to do with polymorphism.
You've already seen that polymorphism applies to the "base" type of the collection:

List<Integer> myList = new ArrayList<Integer>();

In other words, we were able to assign an ArrayList to a List reference, because
List is a supertype of ArrayList.

But what about this?

class Parent { }


class Child extends Parent { }


List<Parent> myList = new ArrayList<Child>();

No, it will not work.

Rule : The type of the variable declaration must match the type you pass to the actual object type. If you declare List<Parent> parentList then whatever you assign to the foo reference MUST be of the generic type <Parent>. Not a subtype of <Parent>. Not a supertype of <Parent>. Just <Parent>.


Wrong:
List<Object> myList = new ArrayList<JButton>(); // NO!
List<Number> numbers = new ArrayList<Integer>(); // NO!

// remember that Integer is a subtype of Number
But these are fine:

List<JButton> myList = new ArrayList<JButton>(); // yes
List<Object> myList = new ArrayList<Object>(); // yes
List<Integer> myList = new ArrayList<Integer>(); // yes


---------------------------------------------------------------

See example:

import java.util.*;
abstract class Animal {
   public abstract void checkup();
}


class Dog extends Animal {
  public void checkup() { // implement Dog-specific code
    System.out.println("Dog checkup");
  }
}


class Cat extends Animal {
  public void checkup() { // implement Cat-specific code
     System.out.println("Cat checkup");
  }
}


public class AnimalDoctor {
  // method takes an array of any animal subtype
  public void checkAnimals(Animal[] animals) {
      for(Animal a : animals) {
         a.checkup();
      }
   }


   public static void main(String[] args) {
     // test it
     Dog[] dogs = {new Dog(), new Dog()};
     Cat[] cats = {new Cat(), new Cat(), new Cat()};
     AnimalDoctor doc = new AnimalDoctor();
     doc.checkAnimals(dogs); // pass the Dog[]
     doc.checkAnimals(cats); // pass the Cat[]
   }
}

Her you see that we can send subtype reference to parent type. But this can't be done in generics, see the next code

public class AnimalDoctorGeneric {
   // change the argument from Animal[] to ArrayList<Animal>
   public void checkAnimals(ArrayList<Animal> animals) {
       for(Animal a : animals) {
          a.checkup();
       }
   }
   public static void main(String[] args) {
      // make ArrayLists instead of arrays for Dog, Cat, Bird
      List<Dog> dogs = new ArrayList<Dog>();
      dogs.add(new Dog());
      dogs.add(new Dog());
      List<Cat> cats = new ArrayList<Cat>();
      cats.add(new Cat());
      cats.add(new Cat());

      // this code is the same as the Array version
      AnimalDoctorGeneric doc = new AnimalDoctorGeneric();
      // this worked when we used arrays instead of ArrayLists
      doc.checkAnimals(dogs); // send a List<Dog>
      doc.checkAnimals(cats); // send a List<Cat>
      
    }
 }

 So what will happen if you will compile this:

 javac AnimalDoctorGeneric.java
 AnimalDoctorGeneric.java:51: checkAnimals(java.util.
 ArrayList<Animal>) in AnimalDoctorGeneric cannot be applied to
 (java.util.List<Dog>)
 doc.checkAnimals(dogs);
    ^
 AnimalDoctorGeneric.java:52: checkAnimals(java.util.
 ArrayList<Animal>) in AnimalDoctorGeneric cannot be applied to 
 (java.util.List<Cat>)
  doc.checkAnimals(cats);
     ^
--------------------------------------------------------------

Her you can see that polymorphism with arrays, where the same scenario (Animal[] can refer to
Dog[], Cat[], or Bird[]) works as you would expect, but not with generics.
So we have two real issues:
1. Why doesn't this work?
2. How do you get around it?

See the code:

public void show() {
       Dog[] dogs = {new Dog(), new Dog()};
       addAnimal(dogs); // no problem, send the Dog[] to the method
}


public void addAnimal(Animal[] animals) {
       animals[0] = new Dog(); // ok, any Animal subtype works
}

It's fine that you can add Dog object into animals because animals is type of Dog

Now suppose any developer has changed some code like...

public void show() {
   Cat[] cats = {new Cat(), new Cat()};
   addAnimal(cats); // no problem, send the Cat[] to the method
}


Now you are sending a cat object to addAnimal() method, which is still same:
  public void addAnimal(Animal[] animals) {
      animals[0] = new Dog(); // Ahhhh! We just put a Dog in a Cat array!
  }

The compiler thinks it is perfectly fine to add a Dog to an Animal[] array, since a Dog can be assigned
to an Animal reference.
The problem is, if you passed in an array of an Animal subtype (Cat, Dog), the compiler does not know.
The compiler does not realize that out on the heap somewhere is an array of type Cat[], not Animal[],
and you're about to try to add a Dog to it. To the compiler, you have passed in an array of type Animal,
so it has no way to recognize the problem.
THIS is the scenario we're trying to prevent, regardless of whether it's an array or
an ArrayList. The difference is, the compiler lets you get away with it for arrays, but
not for generic collections.

Explanation: At runtime the JVM KNOWS the type of arrays, but does NOT know the type of a collection. All the generic type information is removed during compilation, so by the time it gets to the JVM, there is  simply no way to recognize the disaster of putting a Cat into an ArrayList<Dog> and vice versa (and it becomes exactly like the problems you have when you use legacy, non-type safe code).


Solution:
There IS a mechanism to tell the compiler that you can take any generic subtype of the declared argument type because you won't be putting anything in the
collection. And that mechanism is the wildcard <?>. The method signature would change from
public void addAnimal(List<Animal> animals)
to
public void addAnimal(List<? extends Animal> animals)

By saying <? extends Animal>, we're saying, "I can be assigned a collection that is a subtype of List and typed for <Animal> or anything that extends Animal.
And oh yes, I SWEAR that I will not ADD anything into the collection." (There's a little more to the story, but we'll get there.)
So of course the addAnimal() method above won't actually compile even with the wildcard notation, because that method DOES add something.

public void addAnimal(List<? extends Animal> animals) {
    animals.add(new Dog()); // NO! Can't add if we use <? extends Animal>
}

You'll get a very strange error that might look something like this:
javac AnimalDoctorGeneric.java
AnimalDoctorGeneric.java:38: cannot find symbol
symbol : method add(Dog)
location: interface java.util.List<capture of ? extends Animal>
animals.add(new Dog());
^
1 error

Note: The keyword extends in the context of a wildcard represents BOTH subclasses and interface implementations. There is no <? implements Serializable> syntax. If
you want to declare a method that takes anything that is of a type that implements Serializable, you'd still use extends like this:

void show(List<? extends Serializable> list) // odd, but correct  to use "extends"

----------------------------------------------------------------------------------------

However, there is another scenario where you can use a wildcard AND still add to the collection, but in a safe way—the keyword super.
Imagine, for example, that you declared the method this way:

public void addAnimal(List<? super Dog> animals) {
   animals.add(new Dog()); // adding is sometimes OK with super
}


public static void main(String[] args) {
  List<Animal> animals = new ArrayList<Animal>();
  animals.add(new Dog());
  animals.add(new Dog());
  AnimalDoctorGeneric doc = new AnimalDoctorGeneric();
  doc.addAnimal(animals); // passing an Animal List
}

Now what you've said in this line
public void addAnimal(List<? super Dog> animals)
is essentially, "Hey compiler, please accept any List with a generic type that is of type Dog, or a supertype of Dog. Nothing lower in the inheritance tree can come in, but
anything higher than Dog is OK."

Thursday, October 20, 2011

Undestanding hashCode() and equals() on using Map



Understand hashCode() and equals() in HashMap

Always remember that when you are using a class that implements Map or any classes that you
are using as a part of the keys for that map must override the hashCode() and equals()
methods.

Let's see the following example....


-----------------------------------
import java.util.*;


class MapEQ2 {
  public static void main(String[] args) {
       Map<ToDos, String> m = new HashMap<ToDos, String>();
       
       ToDos t1 = new ToDos("Monday");
       ToDos t2 = new ToDos("Monday");
       ToDos t3 = new ToDos("Tuesday");
       System.out.println("Putting first object::");
       m.put(t1, "doLaundry");
       System.out.println("\n Putting second object::");
       m.put(t2, "payBills");
       System.out.println("\n Putting third object::");
       m.put(t3, "cleanAttic");
       System.out.println("\n Map size ::"+m.size());
       System.out.println("\n Map ::: "+m.toString());
  } 
}


class ToDos{
  String day;
  ToDos(String d) { day = d; }
  public boolean equals(Object o) {
      System.out.println("calling equals()..");
     return ((ToDos)o).day == this.day;
  }
/*
   public int hashCode() { 
     System.out.println("calling hashcode()..");
    return 9;
   }


*/
}
-----------------------------------------

See the output:

C:\SCJP6\collection>javac "MapEQ2.java"


C:\SCJP6\collection>java MapEQ2
Putting first object::
Putting second object::
Putting third object::
Map size ::3
Map ::: {ToDos@addbf1=payBills, ToDos@42e816=cleanAttic, ToDos@19821f=doLaundry}


Here you see there is no call to equals method while putting objects on map, because here you have commented hashCode() method. It just calls to default hashCode() method which will generate different keys and so there will be no call to equals method. It calls first to hashCode() and then if it gets duplicate key then it calls to equals() method.

Now if you de-comment the hashCode() method.....

------------------------------------------------
import java.util.*;


class MapEQ2 {
  public static void main(String[] args) {
       Map<ToDos, String> m = new HashMap<ToDos, String>();
       
       ToDos t1 = new ToDos("Monday");
       ToDos t2 = new ToDos("Monday");
       ToDos t3 = new ToDos("Tuesday");
       System.out.println("Putting first object::");
       m.put(t1, "doLaundry");
       System.out.println("\n Putting second object::");
       m.put(t2, "payBills");
       System.out.println("\n Putting third object::");
       m.put(t3, "cleanAttic");
       System.out.println("\n Map size ::"+m.size());
       System.out.println("\n Map ::: "+m.toString());
  } 
}


class ToDos{
  String day;
  ToDos(String d) { day = d; }
  public boolean equals(Object o) {
      System.out.println("calling equals()..");
     return ((ToDos)o).day == this.day;
  }


   public int hashCode() { 
     System.out.println("calling hashcode()..");
    return day.length();
   }




}
------------------------------------------
Now see the output:

C:\SCJP6\collection>javac "MapEQ2.java"


C:\SCJP6\collection>java MapEQ2
 Putting first object::
 calling hashcode()..


 Putting second object::
 calling hashcode()..
 calling equals()..


 Putting third object::
 calling hashcode()..
 calling equals()..


 Map size ::2
 calling hashcode()..
 calling hashcode()..


 Map ::: {ToDos@9=cleanAttic, ToDos@9=payBills}


Here you can see that first it call to hashCode() method and then call tom equals and see if that object is used as key already, then it will overwrite to duplicate key with value for that object. So we get only  two objects this time.

In real-life hashing, it’s not uncommon to have more than one entry in a bucket. Hashing retrieval is a two-step process.


1. Find the right bucket (using hashCode())
2. Search the bucket for the right element (using equals() ).

So be carefull about key when you are going to insert some value in HashMap. Always override hashCode() and equals() method properly.
----------------------------------------

Now change the hashCode() method and compile and run again this program:

public int hashCode() { 
     System.out.println("calling hashcode()..");
    return day.length();
   }

-----------------------------------
This time hashCode() is returning length of day as a hashcode.

See here again output::

C:\SCJP6\collection>javac "MapEQ2.java"


C:\SCJP6\collection>java MapEQ2
Putting first object::
calling hashcode()..


Putting second object::
calling hashcode()..
calling equals()..


Putting third object::
calling hashcode()..


Map size ::2
calling hashcode()..
calling hashcode()..


Map ::: {ToDos@6=payBills, ToDos@7=cleanAttic}

So here what happens, First it put first object ("Monday","doLaundry").
Now when it comes to second ("Monday","payBills"), then it sees the same hashCode and then it calls to equals() method and then in overwrite to the first one object.

In third Map (key,value) object ("Tuesday","cleanAttic"), it sees differnet key and so it does not call equals and just insert it into map.

For any further help or suggestion, you can comment here....

Monday, October 17, 2011

Split cell if data exceeds in itext pdf API

When we insert a big data into a cell then it inserts a page break and goes to next page automatically....

To solve this we can use  setSplitLate(false) method on table to be created in itext pdf doc.

See the complete code here......


package com.example;


import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;


import java.io.FileOutputStream;


public class PdfTableExample {
  public static void main(String[] args) {
 System.out.println("Going to create pdf...");
    Document document = new Document();


    try {
      PdfWriter.getInstance(document, 
    new FileOutputStream("C://Test.pdf"));


      document.open();


      PdfPTable table = new PdfPTable(1); //1 column.
    
     
      String text="Test summary::: bciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozxdfhgdfhjdfjfgfgjo[fkphj.fghjog,ghopdfhgphkifgcvbkjcvlbcophkdf dfopidfhdfkohmgfhoibngfhiofhjpdfghpodfhkdfmhdfkhdopfb d98fjbo sdfopgh]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozx]cblozxjiboz cb" +
      " xscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb" +
      "xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb " +
      "This is a detailed description "+
      "Test summary::: bciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozxdfhgdfhjdfjfgfgjo[fkphj.fghjog,ghopdfhgphkifgcvbkjcvlbcophkdf dfopidfhdfkohmgfhoibngfhiofhjpdfghpodfhkdfmhdfkhdopfb d98fjbo sdfopgh]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozx]cblozxjiboz cb" +
      " xscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb" +
      "xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb " +
      "This is a detailed description "+"Test summary::: bciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozxdfhgdfhjdfjfgfgjo[fkphj.fghjog,ghopdfhgphkifgcvbkjcvlbcophkdf dfopidfhdfkohmgfhoibngfhiofhjpdfghpodfhkdfmhdfkhdopfb d98fjbo sdfopgh]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozx]cblozxjiboz cb" +
      " xscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb" +
      "xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb " +
      "This is a detailed description "+
      "This is a detailed description "+"Test summary::: bciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozxdfhgdfhjdfjfgfgjo[fkphj.fghjog,ghopdfhgphkifgcvbkjcvlbcophkdf dfopidfhdfkohmgfhoibngfhiofhjpdfghpodfhkdfmhdfkhdopfb d98fjbo sdfopgh]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozx]cblozxjiboz cb" +
      " xscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb" +
      "xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb " +
      "This is a detailed description "+
      "This is a detailed description "+"Test summary::: bciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozxdfhgdfhjdfjfgfgjo[fkphj.fghjog,ghopdfhgphkifgcvbkjcvlbcophkdf dfopidfhdfkohmgfhoibngfhiofhjpdfghpodfhkdfmhdfkhdopfb d98fjbo sdfopgh]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozx]cblozxjiboz cb" +
      " xscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb" +
      "xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb " +
      "This is a detailed description "+"This is a detailed description "+"Test summary::: bciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozxdfhgdfhjdfjfgfgjo[fkphj.fghjog,ghopdfhgphkifgcvbkjcvlbcophkdf dfopidfhdfkohmgfhoibngfhiofhjpdfghpodfhkdfmhdfkhdopfb d98fjbo sdfopgh]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmbxcvboixzcjbocvbzxcvbizxjvbiozx]cblozxjiboz cb" +
      " xscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx bxbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzx blzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb" +
      "xcvboixzcjbocvb zxcvbizxjvbiozx]cblozxjiboz cbxscvxukcunbx zxizucvhix czuivh xcvzxblzxckbnx b xbzxcnvbzcbzbciovjbozxcmbzxmb xcvboixzcjbocvb " +
      "This is a detailed description ";
      
      PdfPCell outerTableCell1 = new PdfPCell(new Paragraph("Outer Table :Cell 1"));
      outerTableCell1.setPaddingLeft(15f);
      outerTableCell1.setPaddingRight(20f);
      outerTableCell1.setBorder(0);
 
      PdfPCell outerTableCell2 = new PdfPCell(new Paragraph("Outer Table :Cell 2"));
      outerTableCell2.setPaddingLeft(15f);
      outerTableCell2.setPaddingRight(20f);
 outerTableCell2.setBorder(0);
 
      PdfPCell descCell = new PdfPCell(new Paragraph(new Paragraph(text)));
      descCell.setPaddingLeft(15f);
 descCell.setPaddingRight(20f);
 descCell.setNoWrap(false);
 
 System.out.println("Max height of this cell:"+descCell.getMaxHeight());
 descCell.setBorder(0);
     
      table.addCell(outerTableCell1);
      table.addCell(outerTableCell2);
     table.addCell(descCell);
 
 table.setSplitLate(false);
      document.add(table);


      document.close();
      System.out.println("Completed:See File");


    } catch(Exception e){
    System.out.println("Exception::"+e.getMessage());
      e.printStackTrace();
    }
  }
}

Thursday, October 13, 2011

Create Nested table inside a table on a pdf document using iText

Nested table in iText to cerate pdf using Java
Suppose you are using iText to create pdf document using java, then this program will help you to create a table inside a table.

------------------------------------------------------------------

import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;


import java.io.FileOutputStream;


public class NestedTableExample {
  public static void main(String[] args) {
    Document document = new Document();


    try {
      PdfWriter.getInstance(document, 
    new FileOutputStream("NestedTableDemo.pdf"));


      document.open();


      PdfPTable table = new PdfPTable(2); // 2 columns.


      PdfPCell outerTableCell1 = new PdfPCell(new Paragraph("Outer Table :Cell 1"));
      PdfPCell outerTableCell2 = new PdfPCell(new Paragraph("Outer Table :Cell 2"));
      


      PdfPTable nestedTable = new PdfPTable(3);
      nestedTable.addCell(new Paragraph("Inside Nested Table :Cell 1"));
      nestedTable.addCell(new Paragraph("Inside Nested Table :Cell 2"));
 nestedTable.addCell(new Paragraph("Inside Nested Table : Cell 2"));


      outerTableCell2.addElement(nestedTable);


      table.addCell(outerTableCell1);
      table.addCell(outerTableCell2);
    
      document.add(table);


      document.close();


    } catch(Exception e){
      e.printStackTrace();
    }
  }
}
--------------------------------------------------------------------------------

Wednesday, October 12, 2011

How to add custom marker on Static Map

Please see the folowing URL:


http://maps.googleapis.com/maps/api/staticmap?size=512x512&maptype=roadmap\&
markers=size:mid|color:blue|icon:http://knowledgeserve.in/images/logo.png|San+Francisco,CA|Oakland,CA|San+Jose,CA&sensor=false

See icon: http://knowledgeserve.in/images/logo.png , here you can give the image path, wherever it is..
So change your image link and then copy and paste this URL.

Monday, October 10, 2011

Session timeout interceptor in struts 2

Interceptor continue.....
If you want to use an interceptor which will check whether the session has been expired or not, if it is expired then it will forward to global view( like any jsp that you want to display after session timeout).

You need to do the following coding...
1) Make an interceptor file SessionCheckInterceptor .java

----------------------------------------------------

package com.example.web.interceptor;


import java.util.Map;


import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.vicwalks.web.util.LogManager;
import com.vicwalks.web.util.VicWalkConstants;


public class SessionCheckInterceptor implements Interceptor {

private static final long serialVersionUID = 1L;


public void destroy() {
LogManager.info(this," SessionCheckInterceptor destroy() is called...");
}


public void init() {
LogManager.info(this," SessionCheckInterceptor init() is called...");
}


public String intercept(ActionInvocation actionInvocation) throws Exception {
ActionContext context = actionInvocation.getInvocationContext();
Map<String, Object> sessionMap = context.getSession();
LogManager.info(this," retrived session..."+ sessionMap);
if(sessionMap == null || sessionMap.isEmpty() || sessionMap.get(VicWalkConstants.USER_ID)==null) {
 LogManager.info(this," session expired...");
 return "sessionexpired";
}
String actionResult = actionInvocation.invoke();
return actionResult;
}


}
-------------------------------------------------------------------------------
2) Now do the interceptor entry in struts.xml file...

<interceptors>
       <interceptor name="SessionCheckInterceptor"  
                 class="com.vicwalks.web.interceptor.SessionCheckInterceptor"/>
      <interceptor-stack name="testSessionValidationStack">
                <interceptor-ref name="SessionCheckInterceptor" />
               <interceptor-ref name="defaultStack" />
      </interceptor-stack> 
         
</interceptors>



 <default-interceptor-ref name="testSessionValidationStack"/> 
  <global-results>
           <result name="sessionexpired" >Session_Timeout.jsp</result>
  </global-results> 

--------------------------------------------------------------------------------

Remember if you will use <default-interceptor> in struts.xml file, then it will work for all actions.

Now if you want to apply this interceptor only for some particular actions then you can do it separately inside the action....
---------------------change in struts.xml............

<interceptors>
       <interceptor name="SessionCheckInterceptor"  
                 class="com.vicwalks.web.interceptor.SessionCheckInterceptor"/>
      <interceptor-stack name="testSessionValidationStack">
                <interceptor-ref name="SessionCheckInterceptor" />
               <interceptor-ref name="defaultStack" />
      </interceptor-stack> 
         
</interceptors>




  <global-results>
           <result name="sessionexpired" >Session_Timeout.jsp</result>
  </global-results> 



<action name="testLogin" class="com.example.web.action.TestLoginAction">
   <interceptor-ref name="testSessionValidationStack"/>
<result name="success">LoginSuccess.jsp</result>
<result name="input">login.jsp</result>
<result name="error">error.jsp</result>
</action>


--------------------------------------------------------------------------------
3) Don't forget to see the session configuration in web.xml file under WEB-INF/classes directory

<session-config>
      <session-timeout>30</session-timeout> 
  </session-config>
where 30 minutes represents maximum session time. So if a user is inactive till 30 minutes, session will be timeout and then if you are going to execute some action, interceptor will check the and forward you to the jsp whatever you have suggested in struts.xml under  <global-results>