Friday 22 January 2016

equals() and hashcode() methods

Both methods are from object class. Let us understand one by one
equals() : It compares the content of two objects. If two objects are meaningfully equivalent then it returns true else false. The default implementation of equals() method in object class is same as '==' operator. Declaration of equals() in Object class is as follows :
public boolean equals(Object anObject).

hashcode(): This method gives 32 bit int value, we may say that it is a object Id. The default implementation of hashcode() in object class is, it return the memory address.
Suppose we say, String str="Hello"; then str.hashcode() will return some int number like 69609650, it may vary according to platform. If you wish to use hashcode() other than String class, then you have to override it.

Contract between equals() and hashcode() :
1. If 2 objects are equal using equals() method, then their hashcode must be same.
2. It does not mean that unequal objects must have different hashcode.
3. It does not mean that objects with same hashcode must be equal

Interviewer might confuse you here, but be firm and just remember the contract between these two methods.Soon we will we how and when to override these two methods.

'==' operator vs equals() method

'==' operator : we can use this operator for comparing two objects or to compare primitives. It is not recommended to use it to compare objects as while comparing the objects our focus is on actual equality of objects than the memory location.'==' operator compares the memory location.
Example : String str="Hello";
                 String str2="Java";
here, str==str2 will return false as both objects are stored at different location.
again, say  String str="Java";
                  String str2="Java";
here, str==str2 will return true, as both references are pointing to same object.

equals() method: This method compares the content of two objects. This is overridden method from Object class.Generally, equals method is used to compare two string objects.String class has already overridden equals(), so we can directly use it, but if you wish to compare two objects other than string class then you have to override equals() method. The default implementation of equals() in object class is same as '==' operator. 
Example :  String str="Hello";
                    String str2=new String("Hello");
here, str.equals(str2) will return true.
again, say : String str="Hello";
                    String str2="Java";
here, str.equals(str2) will return false.
You can not use equals() to compare primitives and it is recommended that you use equals() to compare objects and '==' to compare primitives. 


How HashSet internally works ?

HashSet : 
                 HashSet<String> hset=new HashSet<String>();
   It is implementation of Set interface. It stores unique elements, even if we pass duplicates, it will override the elements. So ever you wondered how this uniqueness is manitaned in HashSet. Let us understand.
  HashSet internally uses HashMap. The element we add in set, is stored as a key in hashmap and some dummy value is inserted corresponding to that key. as we know that  always key is unique in hashmap, even if we pass duplicate key, it will just override it. So this is how uniqueness in HashSet is maintained.
In similar ways, TreeSet internally uses TreeMap, LinkedHashSet internally uses LinkedHashMap.

Thursday 21 January 2016

Something about String class

String is a special class in java whose objects are stored in string pool which is part of heap memory. Most of the time interviewer starts java interview with the string class. Most of the people consider it as simplest topic but it's not that much simple when it comes to object creation.
String objects are called as first class objects(first class objects : we do not require new keyword to create object). Internally string is stored as array of characters. Unlike Strings in c, java strings are not null terminated. String class has made programmers life easier :) and java strings are immutable means once the String object is created it can not be modified.
Let us see how to create string object. There are 2 ways to create string object
1. Without using new keyword
2. Using new keyword
let us see one by one.

1. Without using new keyword :
     String str="Hello";
Here, str is a reference to the object 'Hello' which is created on string pool. Each time when string objects are created without using new keyword jvm performs a check whether that object is present in string pool or not, if it is already present in the pool then just reference to that object is returned. No new object is created.
so in above case, jvm will perform the check and it will find that there is no object named 'Hello' in jvm, so it will create one.
Again, if we say String str2="Hello";
Here, new object is not created. jvm will perform check and it will find that 'Hello' object is already there in string pool, so it will return just reference to the 'Hello' object. Now we have two references pointing to the same object on the string pool.
If we say str2=str2.concat(" World"); here again new object will be created but the original one is never modified, that's why we say that string objects are immutable.
Then in this case, str is pointing to 'Hello' object and str2 is pointing to 'Hello World'.

One of the tricky question interviewer may ask here is :
suppose we say String str="How"+"are"+"you"; how many objects are created here ??
The answer is 3. I hope you got the logic :)

2. Using new keyword :
    String str=new String("Hello");
Here, 2 objects are created. Yes 2 objects, you are reading it correctly :)
One object is placed on heap and another is placed in string pool and the reference str implicitly points to the object on heap.In this case, jvm do not perform any check operation like earlier. Always remember whenever you create an object using 'new' keyword, it is stored on heap. So you might be wondering why 2 objects are created here or why they have provided this feature. The answer is simple i.e. re usability. Let us see.
suppose again we say, string str2="Hello"; here, new object is not created, just reference to the earlier object is returned. That's what is re usability.

String str=new String("Hello");
Here, str implicitly points to the object on heap, if you want to make it point to the object on pool then you have to use intern() method, just say :
String str=new String("Hello").intern();
here str will point to the object on pool .

Comparing two strings :
String equality is done by either '==' operator or using equals() method. '==' operator is overloaded for java strings. There is substantial difference between these two. Let us see one by one
1. '==' operator :
    This operator compares memory location of two objects. If they are stored st same memory location then it returns true else false. It checks whether two refrences are pointing to the same object or not. This operator will return true only for the objects which are stored in string pool, because these are the shared objects. If you compared two objects one of which is on pool and other on heap then this operator will always return false, because two objects are always stored at different locations.
Examle : String str="Hello";
                String str2="Hello";
here, only one object is created, str and str2 are pointing to the same object,
so str==str2 will return true.

again, say : String str='Hello';
                    Stirng str2=new String(''Hello");
here, two objects are created and stored at different locations, so this time it will return false.              


2. equals() method :
    This method compares the content of two objects. This is overriden method from Object class.Generally, equals method is used to compare two string objects.
Example :  String str="Hello";
                    String str2=new String("Hello");
here, str.equals(str2) will return true.
again, say : String str="Hello";
                    String str2="Java";
here, str.equals(str2) will return false.


Sometimes, interviewer may ask that why String class is immutable ?
Ans : String objects are shared objects on pool, For a while, assume that String objects are mutable and say, String str="Hello" and String str2="Hello";
So, str and str2 are pointing to same object on string pool. Now, if we say str2.concat("Java"), it will modify the original object so it will reflect in str also. But str does not want that changed object, SO it will create problem for str. That's why string objects are immutable.

Declaration of string class :
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {}

The next question interviewer  may ask is can we design our own class as a immutable class .
Ans : Yes, we can. Declare class as final and its data members as private and final so that nobody will be able to modify the class and its objects.