Sunday, October 20, 2013

TreeSet concepts

When to choose TreeSet ?

 If you want to store the objects in sorted order then choose TreeSet.

Example:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

import java.util.Set;
import java.util.TreeSet;

/**
 *
 * @author Rishitha
 */
public class TreeSetEx {
   
    public static void main(String args[]){
       
        Set<String> tSet = new TreeSet<String>();
        tSet.add("Boat");
        tSet.add("Home");
        tSet.add("Apple");
       
       
        for(String s:tSet){
           
            System.out.println(s);
        }
  }
}

Output:
--------

Apple
Boat
Home

Very important things to learn about TreeSet:

Suppose we have a class Student with
a)sid
b)sname

If we add the student objects to treeset and run we will get big exception.
Run the code given after this exception.
When we added string objects there is no problem but when you add userdefinedclass
objects you are getting exception..

Exception in thread "main" java.lang.ClassCastException: corejava.StudentClass cannot be cast to java.lang.Comparable
    at java.util.TreeMap.compare(TreeMap.java:1188)
    at java.util.TreeMap.put(TreeMap.java:531)
    at java.util.TreeSet.add(TreeSet.java:255)
    at corejava.TreeSetEx.main(TreeSetEx.java:28)

Why it is throwing exception when I am adding StudentClass objects ?
-----------------------------------------------------------------------
Because... We are asking treeset to sort... but treeset is in dilemma
1)Do I need to sort... the StudentClass objects based on sid
or
2)Do I need to sort.. the studentClass objects based on sname....

So.. we need to let Treeset know... how to sort ?
---------------------------------------------------

Ok.... But still you would have a question why exception didn't occur when I added
String objects in to Treeset.

Answer ?
-----------
It is because String class implemented... Comparable Interface and overridden the
compareTo method.

compareTo is the way you can tell the treeset how to sort...the objects you have
added in to TreeSet.

So.. we need to override the comparetTo in StudentClass and TreeSet can take
the help of compareTo in your StudentClass and sorts the objects..

You have to override the compareTo as following to sort objects based
on sid.
If compareTo returns 0 then 2 students need to be considered equal.
If  we return negative Integer then This student is < the student passed as
argument to compareTo
If we return postive integer then This student is > the student passed as
argument to compareTo

public int compareTo(Object o) {
        StudentClass sec = (StudentClass)o;
        if(this.sid == sec.sid) return 0;
        else if(this.sid < sec.sid){
            return -1;
        }else{
            return 1;
        }
       
    }





/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

import java.util.Set;
import java.util.TreeSet;

/**
 *
 * @author Rishitha
 */
public class TreeSetEx {
   
    public static void main(String args[]){
       
        Set<StudentClass> tSet = new TreeSet<StudentClass>();
      
        StudentClass one = new StudentClass();
        one.setSid(1);
        one.setSname("FirstStudent");
       
        StudentClass two = new StudentClass();

        two.setSid(2);
        two.setSname("SecondStudent");
        tSet.add(one);
        tSet.add(two);
       
   }

}


***************************
So the Correct way to sort UserDefinedClass is as follows

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

/**
 *
 * @author Rishitha
 */
 class StudentClass implements Comparable{
    int sid;
    String sname;

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final StudentClass other = (StudentClass) obj;
        if (this.sid != other.sid) {
            return false;
        }
        return true;
    }

  

    @Override
    public int hashCode() {
        int hash = 5;
        return hash;
    }

    @Override
    public int compareTo(Object o) {
        StudentClass sec = (StudentClass)o;
        if(this.sid == sec.sid) return 0;
        else if(this.sid < sec.sid){
            return -1;
        }else{
            return 1;
        }
       
    }

    @Override
    public String toString() {
        return "StudentClass{" + "sid=" + sid + ", sname=" + sname + '}';
    }
   
   
   
   
}


TreeSetEx.java

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

import java.util.Set;
import java.util.TreeSet;

/**
 *
 * @author Rishitha
 */
public class TreeSetEx {
   
    public static void main(String args[]){
       
        Set<StudentClass> tSet = new TreeSet<StudentClass>();
      
        StudentClass one = new StudentClass();
        one.setSid(1);
        one.setSname("FirstStudent");
       
        StudentClass two = new StudentClass();

        two.setSid(2);
        two.setSname("SecondStudent");
        tSet.add(one);
        tSet.add(two);
       
        for(StudentClass s:tSet){
            System.out.println(s);
        }
       
       
      
    }
   
   
   
   
}






















Saturday, October 19, 2013

Hibernate Requirements

To integrate Hibernate with your Java application, you will need to use several Java libraries. The first library is the Java Archive (JAR) file for your JDBC driver, which you will need to find for your specific relational database.

SessionFactory object is thread safe

The details of the join table that contains the links between the two classes in a many-to-many relationship go on the owner class. The Category class owns the relationship, so we add a @JoinTable annotation. The @JoinTable annotation indicates that the relationship requires the creation of an additional link table, so we specify the name of the table containing that information.

The @ManyToMany annotation indicates that the Category class has a many-to-many relationship with the Advert class. This many-to-many relationship is bidirectional, which means that the Advert class has a collection of Category objects, and the Category class has a collection of Advert objects. For many-to-many relationships, we need to tell Hibernate which class is the owner of the relationship. For bidirectional many-to-many relationships, either side can be designated as the owner. For this example, the Category class will be the owner.

Entities can contain references to other entities—either directly as a property or field, or indirectly via a collection of some sort (arrays, sets, lists, etc.). These associations are represented using foreign key relationships in the underlying tables.
When only one of the pair of entities contains a reference to the other, the association is unidirectional. If the association is mutual, then it is referred to as bidirectional.

If both ends of the association managed the foreign keys, then we would encounter a problem when client code called the appropriate set method on both ends of the association. Should two foreign key columns be maintained—one in each direction (risking circular dependencies)—or only one? (And if only one, should altering either side affect it, o r only one?)
Ideally, we would like to dictate that only changes to one end of the relationship will result in any updates to the foreign key; and indeed, Hibernate allows us to do this by marking one end of the association as being managed by the other (in the XML mapping files, this is known as the "inverse" of the parent, whereas in the JPA terminology used by the annotation mappings, it is marked as being "mappedBy" the parent in the @OneToMany annotation).

Caution 
inverse and mappedBy are purely about how the foreign key relationships between entities are saved. They have nothing to do with saving the entities themselves. Despite this, they are often confused with the entirely orthogonal cascade functionality (described in the "Cascading Operations" section of this chapter).
While Hibernate lets us specify that changes to one association will result in changes to the database, it does not allow us to cause changes to one end of the association to be automatically reflected in the other end in the Java POJOs. For example, in a one-to-one bidirectional association between an Email class and a Message class, the code in Listing 4-2 is incomplete even if the Message entity is the inverse of the Email entity:

You should not use a load() method unless you are sure that the object exists. If you are not certain, then use one of the get() methods. The load() methods will throw an exception if the unique id is not found in the database, whereas the get() methods will merely return a null reference.
You can also instruct Hibernate to use a flushing mode for the session with the setFlushMode() method. The getFlushMode() method returns the flush mode for the current session, as follows:
public void setFlushMode(FlushMode flushMode)
public FlushMode getFlushMode()
The possible flush modes are the following:
  • ALWAYS: Every query flushes the session before the query is executed This is going to be very slow.
  • AUTO: Hibernate manages the query flushing to guarantee that the data returned by a query is up-to-date.
  • COMMIT: Hibernate flushes the session on transaction commits.
  • MANUAL: Your application needs to manage the session flushing with the flush() method. Hibernate never flushes the session itself.

By default, Hibernate uses the AUTO flush mode. Generally, you should use transaction boundaries to ensure that appropriate flushing is taking place, rather than trying to "manually" flush at the appropriate times.

By default, Hibernate does not cascade any operations—the default behavior can be overridden at the entity level via the XML mapping files using the default-cascade attribute on the <hibernate-mapping> XML element or in the annotated source files.
The last possible cascading type is delete-orphan. Use delete-orphan to remove a child object from the database when you remove the child from the parent's collection. This cascading type only works on one-to-many associations. The all cascading type does not include delete-orphan—you will have to use "all,delete-orphan", as in the following excerpt from a Hibernate mapping file:

Instead, we want only the catalog to load, possibly with the categories as well. Only when the user drills down into the categories should a subset of the products in that category be loaded from the database.
To manage this problem, Hibernate provides a facility called lazy loading. When enabled (this is the default using XML mappings, but not when using annotations), an entity's associated entities will only be loaded when they are directly requested. For example, the following code loads only a single entity from the database:

Lazy Loading

When you load classes into memory from the database, you don't necessarily want all the information to actually be loaded. To take an extreme example, loading a list of e-mails should not cause the full body text and attachments of every e-mail to be loaded into memory. First, they might demand more memory than is actually available. Second, even if they fit, it could take a long time for all of this information to be obtained.
If you were to tackle this problem in SQL, you would probably select a subset of the appropriate fields for the query to obtain the list; for example:
SELECT from, to, date, subject FROM email WHERE username = 'dcminter';
Hibernate will allow you to fashion queries that are rather similar to this, but it also offers a more flexible approach, known as lazy loading. Certain relationships can be marked as being "lazy," and they will not be loaded from disk until they are actually required.
The default in Hibernate 3 is that classes (including collections like Set and Map) should be lazily loaded. For example, when an instance of the User class given in the next listing is loaded from the database, the only fields initialized will be userId and username.
public class User {
   int userId;
   String username;
   EmailAddress emailAddress;
   Set roles;
}
However, as long as the object is still associated with Hibernate in the appropriate way (see Chapter 9), the appropriate objects for emailAddress and roles will be loaded from the database if they are accessed.
This is the default behavior only; the mapping file can be used to specify which classes and fields should behave in this way.


Required Libraries for Running Hibernate 3.5

Hibernate requires several libraries beyond hibernate3.jar. These libraries are included in the lib/required directory of your Hibernate 3.5 installation. Besides the libraries in lib/required, Hibernate also uses a JPA library, which is included in the lib/jpa directory.
Hibernate 3.5 also requires a bytecode library to function. There are two bytecode libraries shipped with the Hibernate distribution — javassist and CGLib. With Hibernate 3.5, you need to use one or the other. In this book, we will use javassist, as it is the default library.

Introduction to the Life Cycle

After adding Hibernate to your application, you do not need to change your existing Java object model to add persistence marker interfaces or any other type of hint for Hibernate. Instead, Hibernate works with normal Java objects that your application creates with the new operator, or that other objects create. For Hibernate's purposes, these can be drawn up into two categories: objects for which Hibernate has entity mappings, and objects that are not directly recognized by Hibernate. A correctly mapped entity object will consist of fields and properties that are mapped, and that are themselves either references to correctly mapped entities, references to collections of such entities, or "value" types (primitives, primitive wrappers, strings, or arrays of these).
Given an instance of an object that is mapped to Hibernate, it can be in any one of three different states: transient, persistent, or detached.
Transient objects exist in memory, as illustrated in Figure 4-1. Hibernate does not manage transient objects or persist changes to transient objects.
Image from book
Figure 4-1: Transient objects are independent of Hibernate.
To persist the changes to a transient object, you would have to ask the session to save the transient object to the database, at which point Hibernate assigns the object an identifier.

Persistent objects exist in the database, and Hibernate manages the persistence for persistent objects. We show this relationship between the objects and the database in Figure 4-2. If fields or properties change on a persistent object, Hibernate will keep the database representation up-to-date.
Image from book
Figure 4-2: Persistent objects are maintained by Hibernate.
Detached objects have a representation in the database, but changes to the object will not be reflected in the database, and vice versa. This temporary separation of the object and the database is shown in Figure 4-3. A detached object can be created by closing the session that it was associated with, or by evicting it from the session with a call to the session's evict() method. One reason you might consider doing this would be to read an object out of the database, modify the properties of the object in memory, and then store the results some place other than your database. This would be an alternative to doing a deep copy of the object.
Image from book
Figure 4-3: Detached objects exist in the database but are not maintained by Hibernate.
In order to persist changes made to a detached object, the application must reattach it to a valid Hibernate session. A detached instance can be associated with a new Hibernate session when your application calls one of the load(), refresh(), merge(), update(), or save() methods on the new session with a reference to the detached object. After the call, the detached object would be a persistent object managed by the new Hibernate session.

If you are already using hibernate.properties, hibernate.cfg.xml will override any settings in hibernate.properties. Both of these files should be located in the root of your application's classpath.



Generics Concept

Introduction:

Before Jdk1.5.. there is no way to restrict collections to accept only objects of specified type.

Before JDK1.5

If you say List  obList = new ArrayList();
You can add string,Student or Dog or Cat Objects..

But from JDK1.5 using generics...You can restrict list to be only of Strings or Dogs.

Eg:

List<String>  stringListOnly = new ArrayList<String>();

In the angular brackets you have to specify the type of objects you want to add in
to list.If you try to add any object other than String,compilation error occurs.


 Example:
-------------

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

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

/**
 *
 * @author Rishitha
 */
public class GenericEx {
   
   
    public static void main(String args[]){
     
        /** Old Style of using Lists
         * You can add any type of objects
         * In the following example I have added both String Objects
         * and Integer Objects. I can't restrict the list to accept
         * only String Objects.
         *
         * The return type of get method is Object.So you need
         * to cast...
         *
         */
        List preGenericList = new ArrayList();
        preGenericList.add("Anil");
        preGenericList.add("Kumar");
        preGenericList.add(new Integer(10));
       
        for(int i=0;i<preGenericList.size();i++){
           
            Object obName = preGenericList.get(i);
             if(obName instanceof String){
                 String name =(String)obName;
                 System.out.println(name);
             }
           
        }
       
        System.out.println("**************Using Generics *******************");
        /**Here you can only add String objects
         * You need not cast to String specifically because
         * compiler adds cast for you
         */
        List<String> stringListOnly = new ArrayList<String>();
        stringListOnly.add("Anil");
        stringListOnly.add("Kumar");
       
       
        for(int i=0;i<stringListOnly.size();i++){
           
            String name = stringListOnly.get(i);
            System.out.println(name);
           
        }
       
    }
   
   
   
}


Question: How to make list to allow any type of object in to list Using Generics Syntax.

List<Object> anyTypeList = new ArrayList<Object>();
anyTypeList.add(new String());
anyTypeList.add(new Integer(10));

Example:
----------

package corejava;

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

/**
 *
 * @author Rishitha
 */
public class GenericEx {
  
  
    public static void main(String args[]){
    
        /** Following List allows all type of objects using Generics Syntax **/
        List<Object> anyTypeList = new ArrayList<Object>();

        anyTypeList.add(new String("Anil"));

        anyTypeList.add(new Integer(10));
      
        for(int i=0;i<anyTypeList.size();i++){
          
            Object name = anyTypeList.get(i);
            System.out.println(name);
          
        }
      
    }
}







Saturday, October 12, 2013

SCJP Questions


1)


class Mammal{
String name="furry";
String makeNoise(){ return "generic noise";}

}
class Zebra extends Mammal{

Sring name="stripes";
String makeNoise(){return "bray";}

}

public class ZooKeeper{
public static void main(String [] args){ new ZooKeeper().go();}

void go(){

Mammal m = new Zebra();
System.out.println(m.name + m.makeNoise());
}

}

What is the Result ?
2)SCJP:

public class Dark{

    int x =3;
    public static void main(String[] args){

        new Dark().go1();
    }

   void go1(){

       int x;
       go2(++x);
   }

  void go2(int y ){

     int x = ++y;
    System.out.println(x);
  }

}

What is the Result ?

3)
import java.io.*;
class Player {
Player() { System.out.print("p"); }
}
class CardPlayer extends Player implements Serializable {
CardPlayer() { System.out.print("c"); }
public static void main(String[] args) {
CardPlayer c1 = new CardPlayer();
try {
FileOutputStream fos = new FileOutputStream("play.txt");
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(c1);
os.close();
FileInputStream fis = new FileInputStream("play.txt");
ObjectInputStream is = new ObjectInputStream(fis);
CardPlayer c2 = (CardPlayer) is.readObject();
is.close();
} catch (Exception x ) { }
}
}
4)
import java.io.*;

class Keyboard { }
public class Computer implements Serializable {
  private Keyboard k = new Keyboard();
  public static void main(String[] args) {
    Computer c = new Computer();
    c.storeIt(c);
  }
  void storeIt(Computer c) {
    try {
      ObjectOutputStream os = new ObjectOutputStream(
         new FileOutputStream("myFile"));
      os.writeObject(c);
      os.close();
      System.out.println("done");
    } catch (Exception x) {System.out.println("exc"); }
  }
}
 
5)
What is output ?

class Cat { }
class Dog {
public static void main(String [] args) {
Dog d = new Dog();
System.out.println(d instanceof Cat);
}
}
 
6)
 

class Boxing2 {
static Integer x;
public static void main(String [] args) {
doStuff(x);
}
static void doStuff(int z) {
int z2 = 5;
System.out.println(z2 + z);
} }
 
7)
package javaimp;
   class Ouch {
   static int ouch = 7;
    public static void main(String[] args) {
     new Ouch().go(ouch);
      System.out.print(" " + ouch);
    }
    void go(int ouch) {
     ouch++;
     for(int ouch = 3; ouch < 6; ouch++)
       ;
     System.out.print(" " + ouch);
   }
 }
What is the result?
  1. 5 7
  2. 5 8
  3. 8 7
  4. 8 8
  5. Compilation fails

8)

class MyOuter2{
private String x = "Outer2";
void doStuff(){
String z = " local variable";
class MyInner{

public void seeOuter(){

System.out.println("Outer x is "+x);
System.out.println("Local var z is "+z);
}
}
}
}

What is the result ?
 
 
 

Concepts on String,StringBuffer,StringBuilder and String Pool ?

String:
-----------
String is immutable object that means the string content in the String object can't be modified....
String s = "anil";
s = s+"kumar";
But beginners may think that... String s is modified... But what really happens is
original String s doesn't get modified... A new String will be created with "anil" and "kumar"
and the original reference s will be set to new object.Only reference variable is getting modified
but not the contents in the original object.
So the drawback is many intermediate objects get created and it will be a problem if you are doing
multiple concatenations.
 
 String Buffer:
------------------------
When you are doing multiple concatenations use StringBuffer instead of String.
 StringBuffer is synchronized.
StringBuilder:StringBuilder is same as... StringBuffer.Difference is StringBuilder is not 
synchronized.So performance will be more than StringBuffer.But you have to be careful
while using StringBuilder in multithreaded programmes.
 
 
What is string pool ?
------------------------

When you say new String("Anil");

It always creates an object with content String.

Suppose... if you create new String("Anil") in a for loop
with 1000 iterations.. it will create 1000 string objects.

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

Above thing is waste of memory.
So java people decided to create a pool of string objects.

So they given another way to create String objects.

You can create String object with content "Anil" even
in the following manner.

String name = "Anil";

If you write syntax like this... internally java checks if this string
is already in String pool. If it is there.... it returns the reference
to existing String object.

If the object you are trying to create is not existing it will try to
create.... String "Anil" in String pool....

In this case only one object gets created whereas in the first
scenario 1000 object gets created... So you can imagine
how much memory will be saved with this concept....
------------------------------------------------------------------------------

So Finally if you say new String("Anil") always object gets
created

If you say String name = "Anil"; It will be checked in string pool
if the object doesn't exist then only String object with content "Anil" gets
created.

Tuesday, October 8, 2013

Encapsulation

Encapsulation is the ability to hide and protect data stored in Java objects. You may ask, "Who are the bad guys who want to illegally access my data?" It's not about bad guys. When a developer creates a Java class, he or she plans for a certain use pattern of this code by other classes. For example, the variable grossIncome should not be modified directly, but via a method that performs some validation procedures to ensure that the value to be assigned meets application-specific rules.

Encapsulation mechanisms enable the programmer to group data and the subroutines that operate on them together in one place, and to hide irrelevant details from the users of an abstraction

Encapsulation and Access Control

An OOP principle, encapsulation is a mechanism that protects parts of an object that need to be secure and exposes only parts that are safe to be exposed. A television is a good example of encapsulation. Inside it are thousands of electronic components that together form the parts that can receive signals and decode them into images and sound. These components are not to be exposed to users, however, so Sony and other manufacturers wrap them in a strong metallic cover that does not break easily. For a television to be easy to use, it exposes buttons that the user can touch to turn on and off the set, adjust brightness, turn up and down the volume, and so on.
Back to encapsulation in OOP, let's take as an example a class that can encode and decode messages. The class exposes two methods called encode and decode, that users of the class can access. Internally, there are dozens of variables used to store temporary values and other methods that perform supporting tasks. The author of the class hides these variables and other methods because allowing access to them may compromise the security of the encoding/decoding algorithms. Besides, exposing too many things makes the class harder to use. As you can see later, encapsulation is a powerful feature.

Java supports encapsulation through access control. Access control is governed by access control modifiers. There are four access control modifiers in Java: public, protected, private, and the default access level. Access control modifiers can be applied to classes or class members. We'll look at them in the following subsections.

Tight Encapsulation

Encapsulation refers to the combining of fields and methods together in a class such that the methods operate on the data, as opposed to users of the class accessing the fields directly. The term tight encapsulation refers to using encapsulation every time on all the fields of a class, and only providing access to the fields via methods. With tight encapsulation, no fields of an object can be modified or accessed directly; you can only access the fields through a method call.
To implement tight encapsulation, make the fields of a class private and provide public accessor (“getter”) and mutator (“setter”) methods. Because a mutator or accessor method must be invoked to access the fields of the object, tight encapsulation has several key benefits:
  • You can monitor and validate all changes to a field.
  • Similarly, you can monitor and format all access to a field.
  • The actual data type of a field can be hidden from the user, allowing you to change the data type without affecting the code that uses the object, as long as you do not alter the signatures of the corresponding accessor and mutator method.
To demonstrate, let's first look at a class that does not implement tight encapsulation. The following class, named Student1, represents a student with fields for the year (Freshman, Sophomore, Junior, Senior) and percentage grade of a student. The fields of Student1 are public and can be accessed directly:
public class Student1 {
    public String year;
    public double grade;
}
Because the class does not implement tight encapsulation, the fields of a Student1 object can take on any values. The following code is valid, although from an application point of view the values do not make sense:
Student1 s = new Student1();
s.year = "Memphis, TN";
s.grade = -24.5;
The string “Memphis, TN” is not a valid year, and we can assume that a student's grade should never be negative. With tight encapsulation, these issues can easily be avoided because users of the class cannot access its fields directly. By forcing a method call to change a value, you can validate any changes to the fields of the object.
The following Student2 class is similar to Student1 but implements tight encapsulation. It is not possible for year to be an invalid value or grade to be negative or greater than 105.0:
1. public class Student2 {
2.     private String year;
3.     private double grade;
4.
5.     public void setYear(String year) {
6.         if(!year.equals("Freshman")  &&
7.            !year.equals("Sophomore") &&
8.            !year.equals("Junior")    &&
9.            !year.equals("Senior")) {
10.              throw new IllegalArgumentException(
11.                               year + " not a valid year");
12.        } else {
13.            this.year = year;
14.        }
15.    }
16.
17.    public String getYear() {
18.        return year;
19.    }
20.
21.    public void setGrade(double grade) {
22.        if(grade < 0.0 || grade > 105.0) {
23.            throw new IllegalArgumentException(
24.                             grade + " is out of range");
25.        } else {
26.            this.grade = grade;
27.        }
28.    }
29.
30.    public double getGrade() {
31.        return grade;
32.    }
33. }
See if you can determine the result of the following statements:
Student2 s2 = new Student2();
s2.setYear("Junior");
s2.setGrade(-24.5);
Invoking setYear with the argument “Junior” changes the year field to “Junior”. Invoking setGrade with the argument 24.5 causes an IllegalArgumentException to be thrown on line 23. Due to tight encapsulation, it is not possible for the values of Student2 to contain invalid values.
The benefits of encapsulation outweigh any overhead of the additional method calls, and any good OO design uses tight encapsulation in all classes. The next section discusses another important objectoriented design concept: loose coupling.

In the preceding section, you learned that you should hide instance variables by making them private. Why would a programmer want to hide something? In this section we discuss the benefits of information hiding.
The strategy of information hiding is not unique to computer programming—it is used in many engineering disciplines. Consider the electronic control module that is present in every modern car. It is a device that controls the timing of the spark plugs and the flow of gasoline into the motor. If you ask your mechanic what is inside the electronic control module, you will likely get a shrug.
The module is a black box, something that magically does its thing. A car mechanic would never open the control module—it contains electronic parts that can only be serviced at the factory. In general, engineers use the term "black box" to describe any device whose inner workings are hidden. Note that a black box is not totally mysterious. Its interface with the outside world is well-defined. For example, the car mechanic understands how the electronic control module must be connected with sensors and engine parts.
The process of hiding implementation details while publishing an interface is called encapsulation. In Java, the class construct provides encapsulation. The public methods of a class are the interface through which the private implementation is manipulated.
Why do car manufacturers put black boxes into cars? The black box greatly simplifies the work of the car mechanic. Before engine control modules were invented, gasoline flow was regulated by a mechanical device called a carburetor, and car mechanics had to know how to adjust the springs and latches inside. Nowadays, a mechanic no longer needs to know what is inside the module.
Similarly, a programmer using a class is not burdened by unnecessary detail, as you know from your own experience. In Chapter 2, you used classes for strings, streams, and windows without worrying how these classes are implemented.
Encapsulation also helps with diagnosing errors. A large program may consist of hundreds of classes and thousands of methods, but if there is an error with the internal data of an object, you only need to look at the methods of one class. Finally, encapsulation makes it possible to change the implementation of a class without having to tell the programmers who use the class.

INTERFACES VERSUS ABSTRACT CLASSES

The next question is when should you use interfaces and when should you use abstract classes. If two or more classes have lots of common functionality, but some methods should be implemented differently, you can create a common abstract ancestor and as many subclasses inheriting this common behavior as needed. Declare in the superclass as abstract those methods that subclasses should implement differently, and implement these methods in subclasses.
If several classes don't have common functionality but need to exhibit some common behavior, do not create a common ancestor, but have them implement an interface that declares the required behavior. This scenario was not presented in the "Interfaces" section of Lesson 6, but it's going to be a part of the hands-on exercise in the Try It section of this lesson.
Interfaces and abstract classes are similar in that they ensure that required methods will be implemented according to required method signatures. But they differ in how the program is designed. While abstract classes require you to provide a common ancestor for the classes, interfaces don't.
Interfaces could be your only option if a class already has an ancestor that cannot be changed. Java doesn't support multiple inheritance — a class can have only one ancestor. For example, to write Java applets you must inherit your class from the class Applet, or in the case of Swing applets, from JApplet. Here using your own abstract ancestor is not an option.
While using abstract classes, interfaces, and polymorphism is not a must, it certainly improves the design of Java code by making it more readable and understandable to others who may need to work on programs written by you.

Cloning in Java


Cloning: Cloning means creating the new object with the same state as the object you are cloning.

Default Cloning in Java: Shallow Cloning

I will explain Shallow Cloning with an example.

Suppose if I have StudentShallowEx class with following members

a)sid(1)
b)sname(String)("Anil")
c)address (This is an instance of class Address)

Address class has following members:

a)city(String)

When you clone the StudentShalloEx object(one in the following code) by calling clone() method,
new  StudentShalloEx will be created with the state of the original object you are trying to clone.
The drawback of this... is referenes will be copied to cloned object.So if you change the state
of the address object in cloned object,original object will be affected.

1)sid same as in  original object i.e 1
2)and sname as "Anil"
3)and the address reference in original object is copied to address reference in cloned object,so the
   address reference in original object and cloned object points to the same Address object thereby
   any changes you make to address reference in cloned will affect the original object.....

So,if you modify the address reference in cloned object it will change the address in
the original object.

But even if you change the sid in cloned object it won't affect the sid in the original object.

Imp Point: So if your object has only primitives and immutable objects like String,shallow
copy will be sufficient.

But if you have other class objects which are mutable like address in our example you have
to create deep copy.... so that changes you make to cloned object will not affect the original
object...





ShallowCloning Example Code:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

/**
 *
 * @author Rishitha
 */
public class Address {
    private String city;
   
    Address(){
       
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

  
   
   
   
}
 


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

/**
 *
 * @author Rishitha
 */
public class StudentShallowEx implements Cloneable{
  
    private int sid;
    private String sname;
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public StudentShallowEx() {
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }
  
  
    public static void main(String args[])throws CloneNotSupportedException{
      
        StudentShallowEx one = new StudentShallowEx();
        one.sid=1;
        one.sname="Anil";
        Address add1 = new Address();
        add1.setCity("HYD");
        one.setAddress(add1);
        System.out.println(one.sid);
        System.out.println(one.getAddress().getCity());
        StudentShallowEx two = (StudentShallowEx)one.clone();
        two.getAddress().setCity("HYD is modified because it is shallow copying");
        two.setSid(2);
        System.out.println(one.sid);
        System.out.println(one.getAddress().getCity());
    }
  
  
}

DeepCloning:

When you do the deep clone of the Student,when you change the address in cloned object
it won't affect the address state in the original object.

In shallow cloning if you change the state of the address in cloned object,it will change
the address state in original object

To do deep cloning you have to do the following changes
--------------------------------------------------------------------------
1)Address class should implement Cloneable
2)It should override the clone method
3)StudentDeepCopy should override the clone method.

Deep Cloning code:


 /*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

/**
 *
 * @author Rishitha
 */
public class Address implements Cloneable{
    private String city;
   
    Address(){
       
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
   
   
   
}

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package corejava;

/**
 *
 * @author Rishitha
 */
public class StudentDeepEx implements Cloneable{
   
    private int sid;
    private String sname;
    private Address address;

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public StudentDeepEx() {
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

  
    protected Object clone() throws CloneNotSupportedException {
       StudentDeepEx cloneOb = (StudentDeepEx)super.clone();
       cloneOb.address = (Address)cloneOb.getAddress().clone();
       return cloneOb;
    }
   
   
    public static void main(String args[])throws CloneNotSupportedException{
       
        StudentDeepEx one = new StudentDeepEx();
        one.sid=1;
        one.sname="Anil";
        Address add1 = new Address();
        add1.setCity("HYD");
        one.setAddress(add1);
        System.out.println(one.sid);
        System.out.println(one.getAddress().getCity());
        StudentDeepEx two = (StudentDeepEx)one.clone();
        two.getAddress().setCity("HYD is modified because it is shallow copying");
        two.setSid(2);
        System.out.println(one.sid);
        System.out.println(one.getAddress().getCity());
    }
   
   
}











Monday, October 7, 2013

Interview Questions

1)What is difference between comparable and comparator interface ?Why you need comparator when you have comparable interface ?

2)What is difference between ArrayList and Vector and LinkedList ?
You should be able to explain... the difference between them
and in what situation you prefer ArrayList over Vector.... or
When to use ArrayList over LinkedList ?
3)What is default cloning and difference between shallow and deep cloning in java ?
4)Why string is immutable and how to create immutable class in java ? 
5)What is concurrentHashmap ?
6)How hashing related collections work ?
7)Difference between hashtable and hashmap, can we use hashmap in multithreaded scenario ?