Monday, December 23, 2013

Enumeration vs Iterator in Java

In this post, we'll see what is enumeration and Iterator and differences between them with the help of some examples.


Enumeration
Enumeration is a public interface in Java, introduced in JDK 1.0, which provides the ability to enumerate through sequences of elements. It is found under java.util package.

An object that implements the Enumeration interface generates a series of elements, one at a time. Successive calls to the nextElement method return successive elements of the series.

Method of Enumeration Class
Method  Description Exception
boolean  hasMoreElements() Tests if this enumeration contains more elements.element to provide; false otherwis
E   nextElement() Returns the next element of this enumeration if this enumeration object has at least one more element to provide. NoSuchElementException - if no more elements exist.

Example
 import java.util.Enumeration;  
 import java.util.Hashtable;  
 import java.util.Vector;  
 public class EnumerationDemo {  
      public static void main(String[] javalatte) {  
           Vector<String> l = new Vector<String>();   
           l.add("java");  
           l.add("-");  
           l.add("latte");  
           l.add(".");  
           l.add("blogspot");  
           l.add(".com");            
           Enumeration<String> en = l.elements();  
           while(en.hasMoreElements()){  
                System.out.println(en.nextElement());  
           }  
           System.out.println();  
           Hashtable<String, String> ht = new Hashtable<String,String>();  
           ht.put("java", "1");  
           ht.put("latte", "2");  
           ht.put("blogspot", "3");  
           ht.put("com", "4");  
           Enumeration<String> enHash = ht.elements();  
           while(enHash.hasMoreElements()){  
                System.out.println(enHash.nextElement());  
                ht.remove("com"); // you can remove while iterating and no ConcurrentModificationException  
           }  
           System.out.println(enHash.nextElement()); // thows NoSuchElementException as not element exist.   
      }  
 }  
Sample Output
java
-
latte
.
blogspot
.com

3
2
1
Exception in thread "main" java.util.NoSuchElementException: Hashtable Enumerator
at java.util.Hashtable$Enumerator.nextElement(Unknown Source)

at EnumerationDemo.main(EnumerationDemo.java:28)


Iterator
Iterator is a public interface in Java.util package, which allows iterating through elements of the collections objects that implement the Collections framework (such as ArrayList, LinkedList, etc.). This was introduced in JDK 1.2 and replaced the Enumerator within the Java Collections Framework.
The java.util.Iterator interface allows the iteration of container classes. Each Iterator provides a next() and hasNext() method, and may optionally support a remove() method. Iterators are created by the corresponding container class, typically by a method named iterator().
Additionally, for java.util.List there is a java.util.ListIterator with a similar API but that allows forward and backward iteration, provides its current index in the list and allows setting of the list element at its position.
The J2SE 5.0 release of Java introduced the Iterable interface to support an enhanced for (foreach) loop for iterating over collections and arrays.

Method of Iterator Class
Method  Description Exception
boolean  hasNext() Returns true if the iteration has more elements.
E  next() Returns the next element in the iteration NoSuchElementException - if no more elements exist.
void  remove() Removes from the underlying collection the last element returned by this iterator (optional operation). UnsupportedOperationException -  if the remove operation is not supported by this iterator                                                   IllegalStateException - if the next method has not yet been called, or the remove method has already been called after the last call to the next method


Example
 import java.util.ArrayList;  
 import java.util.Iterator;  
 public class IteratorDemo {  
      public static void main(String[] javalatte) {  
           ArrayList<String> ar = new ArrayList<String>();  
           ar.add("java");  
           ar.add("-");  
           ar.add("latte");  
           ar.add("blogspot");  
           ar.add(".");  
           ar.add("com");  
           Iterator<String> it = ar.iterator();  
           while(it.hasNext()){  
                System.out.println(it.next());  
           }  
           //System.out.println(it.next()); //it throws NoSuchElementException as not element exist.   
           System.out.println();  
           Iterator<String> it1 = ar.iterator();  
           while(it1.hasNext()){  
                System.out.println(it1.next());  
                ar.remove(3); // it will throw ConcurrentModificationException  
           }            
      }  
 }  
Sample Output
java
-
latte
blogspot
.
com

java
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)

at IteratorDemo.main(IteratorDemo.java:22)


Difference between Enumeration and Iterator
Both are interface,not an implementation, and even new libraries sometimes still use the old Enumeration.
From the above discussion, following differences are clear.


  • Method names have been improved.
    Enumeration  methods   Iterator
    hasMoreElement() hasNext()
    nextElement() next()
    remove()
  • Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics. we'll see example of this next.
  • Iterators are fail-fast,when one thread changes the collection with add or remove operations or you modify the collection, while another thread is traversing it through an Iterator using hasNext() or next() method, the iterator fails quickly by throwing ConcurrentModificationException.
  • Enumeration is applicable for Legacy Classes.


Iterator remove() method example
import java.util.ArrayList;  
 import java.util.Iterator;  
 public class IteratorRemoveDemo {  
      public static void main(String[] args) {  
           ArrayList<String> ar = new ArrayList<String>();  
           ar.add("java");  
           ar.add("-");  
           ar.add("latte");  
           ar.add("blogspot");  
           ar.add(".");  
           ar.add("com");  
           Iterator<String> it = ar.iterator();  
           System.out.println("Array Size= "+ar.size());  
           while(it.hasNext()){  
                System.out.println(it.next());  
                it.remove();                 
           }  
           System.out.println("Array Size= "+ar.size());  
      }  
 }  
Sample Output
Array Size= 6
java
-
latte
blogspot
.
com

Array Size= 0

Note: One point to remember while using remove() method, if you call remove() before hasNext() java.lang.IllegalStateException will occur.
      Iterator<String> it = ar.iterator();  
           it.remove();  // new line in the above code
           System.out.println("Array Size= "+ar.size());  
           while(it.hasNext()){  

In addition, you can produce an Enumeration for any Collection by using the Collections.enumeration() method, as seen in the following example:
 import java.util.ArrayList;  
 import java.util.Collections;  
 import java.util.Enumeration;  
 public class newLatte {  
      public static void main(String[] args) {  
           ArrayList<String> ar = new ArrayList<String>();  
           ar.add("java");  
           ar.add("-");  
           ar.add("latte");  
           ar.add("blogspot");  
           ar.add(".");  
           ar.add("com");  
           Enumeration<String> en = Collections.enumeration(ar);  
           while(en.hasMoreElements()){  
                System.out.println(en.nextElement());  
           }  
      }  
 }
Sample output
java
-
latte
blogspot
.

com



Related Post
How to iterate over Map in 4 ways
Over of Java Collection Framework

If you know anyone who has started learning java, why not help them out! Just share this post with them. Thanks for studying today!...

Wednesday, December 18, 2013

Constructor, constructor chaining and overloading of constructor in Java

Everybody knows what a constructor is i.e, constructor create new object but the purpose of this post is cover detailed concepts about constructor which includes rules for creating and defining constructors, constructor chaining and what is the need of private constructor and when does compiler provide the default constructor for us. 

Objects are constructed. You can't make a new object without invoking a constructor.
In fact, you can't make a new object without invoking not just the constructor of the object's actual class type, but also the constructor of each of its superclasses.

Constructors are special methods that create and return an object of the class in which they’re defined. Constructors have the same name as the name of the class in which they’re defined, and they don’t specify a return type—not even void

3 Steps of object declaration, creation and assignment.
  • Step 1. Declare a reference variable
    • Latte mylatte = new Latte();
    • Make a new reference variable of a class or interface type
  • Step 2. Create an object
    • Latte mylatte = new Latte();
  • Step 3. Link the object and the refernce
    • Latte mylatte new Latte();
    • Assign the new object to the reference.

Q. Are we here calling a method name Latte()? Because it sure look like it.
No We're calling the Latte constructor.
A constructor does look and feel a lot like a method, but it is not a method. It's got the code the run when you say new.  The only way to invoke a constructor is with the new keyword.


Constructor Basics
Every class, including abstract classes, MUST have a constructor. Store this into your brain. It is not necessarily to type it just because class must have one.

A Constructor look like:
 class latte {  
  latte(){ }       
 }  

Have you noticed something is missing? There is no return type!

Two point to remember about constructors:
  • they have no return type 
  • their names must exactly match the class name

Typically, constructors are used to initialize instance variable state, for instance
 class latte {  
  int size;  
  String name;  
  latte(int size, String name){  
  this.size=size;  
  this.name=name;  
  }       
 }

Here you may be noticed that latte class doesn't have no-arg constructor. That means the following will fail to compile:

latte l = new latte(); // won't compile

but the following will compile

latte l = new latte(5,"caffee"); // no problem, argument match the latte constructor

What we get from this, is that it's very common and may be desirable for a class to have a no-arg constructor, regardless of how many other overloaded constructor is present in the class.
Oh, yes, constructor can be overloaded.


How Constructor Chaining works



Consider the basic animal hierarchy where we assume Horse extends Animal and Animal extends Object.

 class Animal{  
 }  
 Class Horse extends Animal{  
 }  


We know that constructors are invoked at runtime when you say new on some class type as follows:
Horse h = new Horse();

  1. Horse constructor is invoked. Every constructor invokes the constructor of its superclass with an (implicit) call to super(), unless the constructor invokes an overloaded constructor of the same class.
  2. Animal constructor is invoked because Animal is the superclass of Horse.
  3. Object constructor is invoked.At this point we're on the top of the stack.
  4. Object instance variables are given their explicit values. By explicit values, we mean values that are assigned at the time the variables are declared.
  5. like "int x = 5", where "5" is the explicit value (as opposed to the default value) of the instance variable.
  6. Object constructor completes.
  7. Animal instance variables are given their explicit values.
  8. Animal constructor completes.
  9. Horse instance variables are given their explicit values (if any)
  10. Horse constructor completes.

Summary













The MUST remember rules for constructor to answer any interview questions regarding constructor

  1. Constructors can use any access modifier, including private.
    A private constructor means only code within the class itself can instantiate an object of that type, so if the private constructor class wants to allow an instance of the class to be used, the class must provide a static method or variable that allows access to an instance created from within the class. Click here to see more
  2. The constructor name must match the name of the class.
  3. Constructors must not have a return type.
  4. It's legal (but stupid) to have a method with the same name as the class, but that doesn't make it a constructor. If you see a return type, it's a method rather than a constructor.
  5. If you don't type a constructor into your class code, a default constructor will be automatically generated by the compiler. we will see this in the next section
  6. The default constructor is ALWAYS a no-arg constructor.
  7. If you want a no-arg constructor and you've typed any other constructor(s) into your class code, the compiler won't provide the no-arg constructor for you.
  8. Every constructor has, as its first statement, either a call to an overloaded constructor (this()) or a call to the superclass constructor (super()), although remember that this call can be inserted by the compiler.
  9. If you do type in a constructor and you do not type in the call to super() or a call to this(), the compiler will insert a no-arg call to super() for you, as the very first statement in the constructor.
  10. A call to super() can be either a no-arg call or can include arguments passed to the super constructor.
  11. You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs.
  12. Only static variables and methods can be accessed as part of the call to super() or this().
  13. Abstract classes have constructors, and those constructors are always called when a concrete subclass is instantiated.
  14. The only way a constructor can be invoked is from within another constructor. In other words, you can't write code that actually calls a constructor. You try by yourself to check this.

Whether a Default Constructor Will Be Created
The following example shows a Horse class with two constructors:
class latte{  
      latte(){ }  
      latte(String name){ }  
 }  
In this case compiler won't put default constructor.
class latte{  
      latte(String name){ }  
 } 
In this case also compiler won't put default constructor.
 class latte{ } 
In this case compiler will generate a  default constructor for the preceding class, because the class doesn't have any constructors defined

what about this class?
class latte{  
      void latte(){ }  
 } 
It might look like the compiler won't create one, since there already is a constructor in the latte class.What's wrong with the latte() constructor? It isn't a constructor at all! It's simply a method that happens to have the same name as the class.



Overloaded constructor

Overloading a constructor means typing in multiple versions of the constructor, each having a different argument list, like the following examples:
 class Latte{  
      Latte(){  
      }  
      Latte(String name){  
      }  
      Latte(int size){  
      }  
      Latte(String name, int size){  
      }  
      Latte(int size,String name){  
      }  
 }
If you have 2 constructor that took only an int, for example, the class wouldn't compile. What you name the parameter variable doesn't matter. It's the variable type and order that matters. A constructor that takes a string followed by an int, is not the same as one that takes an int followed by string.
Overloading a constructor is typically used to provide alternate ways for clients to instantiate objects of your class. For example, if a client knows the animal name, they can pass that to an Animal constructor that takes a string. But if they don't know the name, the client can call the no-arg constructor and that constructor can supply a default name.

Five different constructor means five different ways to make a new Latte object.


Example
 public class JavaLatte {  
      String name;  
      JavaLatte(){  
           this("Cafee Latte");  
      }  
      JavaLatte(String name){  
           this.name=name;  
      }  
      public static void main(String javalatte[]){  
           JavaLatte jv = new JavaLatte();  
           System.out.println(jv.name);  
           JavaLatte jv1 = new JavaLatte("Cappicino");  
           System.out.println(jv1.name);  
      }       
 }

The key point to get from this code example. Rather than calling super(), we're calling this(), and this() always means a call to another constructor in the same class. OK, fine, but what happens after the call to this()? Sooner or later the super() constructor gets called, right? Yes indeed. A call to this() just means you're delaying the inevitable. Some constructor, somewhere, must make the call to super().


The benefit of having one constructor invoke another overloaded constructor is to avoid code duplication.
The call to super() must be the first statement in each constructor.For instance, following code won't compile.
 class Latte{  
      Latte(){  
      }  
 }  
 class JavaLatte extends Latte{  
      int size;  
      JavaLatte(){  
           size=5;  
           super();  
      }  
 }  

Superclass constructor with arguments
If superclass constructor has arguments? Can you pass something in to the super() call?
Of course. If you couldn't, you had never be able to extend a class that didn't have a no-arg constructor.
Imagine a scenario :
All animal have a name. There is getName() method in class Animal that returns the value of the name instance variable. The instance variable is marked private, but the subclass inherits getName() method. So here is the problem Horse has a getName() method, but does not have the name instance variable.
Horse has to depend on the Animal part of himself to keep the name instance variable and return it when someone call getName() on a Horse object
Question is how Animal part get the name???
The only reference Horse has to the animal part of himself is through super(), so this is the place where Horse send the name to the Animal object.
abstract class Animal{  
      private String name;  
      public String getName(){  
           return name;  
      }  
      public Animal(String name){  
           this.name=name;  
      }  
 }  
 class Horse extends Animal{  
      Horse(String name){  
           super(name);  
      }  
 }  
 public class HorseDemo{  
      public static void main(String[] javalatte){  
           Horse h = new Horse("HORSE ONE");  
           System.out.println(h.getName());  
      }  
 }  

Overridden constructor?
One last point on the whole default constructor thing, constructors are never inherited. They aren't methods. They can't be overridden (because they aren't methods and only instance methods can be overridden). So the type of constructor(s) your superclass has in no way determines the type of default constructor you'll get. Some folks mistakenly believe that the default constructor somehow matches the super constructor, either by the arguments the default constructor will have (remember, the default constructor is always a no-arg), or by the arguments used in the compiler-supplied call to super(). So, although constructors can't be overridden, you've already seen that they can be overloaded, and typically are.




Q1Doesn't the compiler always make a no-arg constructor for you?
Ans:
No. The compiler gets involved with the constructor making only if you don't say anything at all about constructor. If you write a constructor that takes arguments, and you still want a no-arg constructor, you'll have to build the no-arg constructor yourself.

Q2Do constructor need to be public?
Ans: No. Constructor can be public, private or default
Puzzle Question:
class latte{   
      String name;   
      latte(){   
           return;   
      }   
      latte(String name){   
           this.name=name;   
           return;   
      }   
 }   
 public class javalatte{   
      public static void main(String javalatte[]){   
           latte l = new latte("java.latte");   
           System.out.println(l.name);   
      }   
 }   
Guess the output?




If you know anyone who has started learning java, why not help them out! Just share this post with them. Thanks for studying today!...

Thursday, November 28, 2013

Integer constant pool in java

In this post, we'll look into Integer Wrapper class and its Integer constant pool concept with reason behind it for creating such pool with few examples.

What is Integer Class?
The Integer class wraps a value of the primitive type int in an object. An object of type Integer contains a single field whose type is int.

In addition, this class provides several methods for converting an int to a String and a String to an int, as well as other constants and methods useful when dealing with an int.

Before moving further please guess the output of the following program. If you are able to answer them all correct, then it's means you know how Java Integer Constant pool works :)

You can find the answer at the bottom of the post. If your answers are not right, then read further to know why Integer class behave in a unusual way.

Integer i = 10 vs Integer j = new Integer(10)
After compiling this class, I tried to de-compile the same class. What is got it this
So java called Integer.valueOf() whenever we create object of Integer class as Integer i = 10;

Integer.valueOf()
Let's see what does this function do. As per the Oracle doc, it says 
public static Integer valueOf(int i)
Returns an Integer instance representing the specified int value. 

If a new Integer instance is not required, this method should generally be used in preference to the constructor Integer(int), as this method is likely to yield significantly better space and time performance by caching frequently requested values. This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.

To explore further, let's have a look at the code of Integer.valueOf() function 

It's clear from the above code that when we call valueof() function with value range from -128 to 127, it always cache the value.



Integer.cache is the class that help us in caching in Integer values. The size of the cache may be controlled by the 
-XX:AutoBoxCacheMax= <size>
Or this can achieved with system property
-Djava.lang.Integer.IntegerCache.high=<size>

In other words, when we create object of Integer class 
Integer i = 10;
Integer j = new Integer(10); 
both refer to the same instance in the pool.
So you get the same reference if value is between -128 to 127 and you call valueOf() else it just returns new Integer(int). As reference is same your == operator works for integer returned by valueOf() between this range.

Java caches the integer objects in the range -128 to 127. So, when you try to assign a value in this range to a wrapper object, the boxing operation will invoke Integer.valueOf() method and in turn it will assign a reference to the object already in the pool.
On the other hand, if you assign a value outside this range to a wrapper reference type, Integer.valueOf will create a new Integer object for that value. And hence, comparing the reference for Integer objects having value outside this range will give you false.

I hope at this point, you got the idea of Integer Constant pool. So have a look at the above code for which you have to guess the output and see this time, will you able to answer all the question correct.

Summary of Integer constant pool


Answers
IntegerClassExampleOne 
i==j is not equal

IntegerClassExampleTwo
i==j is not equal

IntegerClassExampleThree
i==j is not equal

IntegerClassExampleFour
i==j is equal



If you know anyone who has started learning java, why not help them out! Just share this post with them. Thanks for studying today!...

Sunday, November 24, 2013

Object equality, hashCode() vs equals() in Java

In this post, we'll see what makes two object equals and when to override equals() and hashCode() method. Also we'll see what is difference between Reference equality and Object Equality.

Let's first see what does Object class methods equals() and hashCode() says.
equals()
hashCode()

Overriding equals()
This is what Object equals() method look like.
public boolean equals(Object obj) {
        return (this == obj);
}
It simply using the == operator to compare.
Comparing two object references using the == operator evaluates to true only when both references refer to the same object because == simply looks at the bits in the variable, and they're either identical or they're not.

Let's see an example to understand this. 

public class ReferenceDemo {  
  public static void main(String[] javalatte) {  
  Dog d1 = new Dog("DogA");  
  Dog d2 = new Dog("DogA");  
  if(d1.equals(d2)){  
   System.out.println("Dog's are equal");  
  }else {  
   System.out.println("Dog's are not equal");  
  }  
  Dog d = new Dog("Tommy");  
  Dog tommy1 = d;  
  Dog tommy2 = d;  
  if(tommy1.equals(tommy2)){  
   System.out.println("Dog's are equal");  
  }else {  
   System.out.println("Dog's are not equal");  
  }  
  }  
 }  
 class Dog{  
  private String name;  
  Dog(String title){  
  this.name=title;  
  }  
  public String getTitle(){  
  return name;  
  }  
 }  
Sample Output
Dog's are not equal
Dog's are equal
Now it clear why we got this output because equals method looks at the bits in the variable, and they're either identical or they're not.

If you see the String class and the wrapper classes have overridden the equals() method (inherited from class Object), so that you could compare two different objects (of the same type) to see if their contents are meaningfully equivalent. If two different String instances both hold the String value "javalatte", as far as you're concerned they are equal. The fact that the value "javalatte lives in two separate objects doesn't matter.

String class overridden equals() method code
public boolean equals(Object anObject) {
     if (this == anObject) {
         return true;
     }
     if (anObject instanceof String) {
         String anotherString = (String)anObject;
         int n = count;
         if (n == anotherString.count) {
             char v1[] = value;
             char v2[] = anotherString.value;
             int i = offset;
             int j = anotherString.offset;
             while (n-- != 0) {
                 if (v1[i++] != v2[j++])
                     return false;
             }
             return true;
         }
     }
     return false;
 }
To clear this picture, let's see an another example and have a look on the output
 public class StringReferenceDemo {  
  public static void main(String[] java) {  
  String s1 = new String("javalatte");  
  String s2 = new String("javalatte");  
  if(s1.equals(s2)){  
   System.out.println("String's are equal");  
  }else{  
   System.out.println("String's are not equal");  
  }  
  }  
 }  
Sample Output
String's are equal
If you see the "javalatte" string live in separate object, but they are equal because String class has overridden the equals() method.

When you really need to know if two references are identical, use ==. But when you need to know if the objects themselves (not the references) are equal, use the equals() method. For each class you write, you must decide if it makes sense to consider two different instances equal. For some classes, you might decide that two objects can never be equal. For example, imagine a class Car that has instance variables for things like make, model, year, configuration—you certainly don't want your car suddenly to be treated as the very same car as someone with a car that has identical attributes.
Your car is your car and you don't want your neighbor Pardeep driving off in it just because, "hey, it's really the same car; the equals() method said so".So no two cars should ever be considered exactly equal.
If two references refer to  one car, then you know that both are talking about one car, not two cars that have the same attributes. So in the case of a Car you might not ever need, or want, to override the equals() method.

What It Means If You Don't Override equals()
If you don't override a class's equals() method, you won't be able to use those objects as a key in a hashtable and you probably won't get accurate Sets, such that there are no conceptual duplicates.
The equals() method in class Object uses only the == operator for comparisons, so unless you override equals(), two objects are considered equal only if the two references refer to the same object.
As you have seen in the "ReferenceDemo" class where
Dog d1 =  new Dog("DogA");
Dog d2 =  new Dog("DogA");
di and d2 are not equal

Let's look at what it means to not be able to use an object as a hashtable key.
Imagine you have a Dog, a very specific car that you want to put in a HashMap, so that you can search on a particular Dog and retrieve the corresponding Person object that represents the owner. So you add the Dog instance as the key to the HashMap. But now what happens when you want to do a search? You want to say to the HashMap collection, "Here's the Dog, now give me the Person object that goes with this Dog." But now you're in trouble unless you still have a reference to the exact object you used as the key when you added it to the Collection. In other words, you can't make an identical Car object and use it for the search.
The bottom line is this: if you want objects of your class to be used as keys for a hashtable (or as elements in any data structure that uses equivalency for searching for—and/or retrieving—an object), then you must override equals() so that two different instances can be considered the same.

Understanding Hashcodes
Imagine a set of buckets lined up on the floor. Someone hands you a piece of paper with a name on it. You take the name and calculate an integer code from it by using A is 1, B is 2, and so on, and adding the numeric values of all the letters in the name together. A given name will always result in the same code;

We don't introduce anything random, we simply have an algorithm that will always run the same way given a specific input, so the output will always be identical for any two identical inputs. So far so good? Now the way you use that code is to determine which bucket to place the piece of paper into.Now imagine that someone comes up and shows you a name and says, "Please retrieve the piece of paper that matches this name." So you look at the name they show you, and run the same hashcode-generating algorithm. The hashcode tells you in which bucket you should look to find the name.
You might have noticed a little flaw in our system, though. Two different names might result in the same value. For example, the names Amy and May have the same letters, so the hashcode will be identical for both names. That's acceptable, but it does mean that when someone asks you  for the Amy piece of paper, you'll still have to search through the target bucket reading each name until we find Amy rather than May. The hashcode tells you only which bucket to go into, but not how to locate the name once we're in that bucket.

How some of the collections use hashcodes
The above distributed-across-the-buckets example is similar to the way hashcodes are used in collections. When you put an object in a collection that uses hashcodes, the collection uses the hashcode of the object to decide in which bucket/slot the object should land. Then when you want to fetch that object you have to give the collection a reference to an object that the collection compares to the objects it holds in the collection. As long as the object you're trying to search for has the same hashcode as the object you're using for the search then the object will be found.

But…and this is a Big One, imagine what would happen if, going back to our name example, you showed the bucket-worker a name and they calculated the code based on only half the letters in the name instead of all of them. They'd never find the name in the bucket because they wouldn't be looking in the correct bucket!
Now can you see why if two objects are considered equal, their hashcodes must also be equal? Otherwise, you'd never be able to find the object since the default hashcode method in class Object virtually always comes up with a unique number for each object, even if the equals() method is overridden in such a way that two or more objects are considered equal

What makes two object equal?
First, we have to ask - what makes two Dog references duplicate? They must be considered equal. Is it simply two references to the very same object, or it is two different object both have the same title?
This  brings up a key issue : reference equality vs object equality

Reference equality






if ( tommy == jakky ) {
// both references referring to the same object on the heap
}








Two references, one object on the heap.
Two references that refer to the same object on the heap are equal. If you call the hashCode() method on the both references, you will get the same result. If you don't override the hashCode() method, the default behavior is that each object will get a unique number.

If you want to know if the 2 references are really referring to the same object, use the == operator, which compares the bits in the variable. If both references point to the same objects, the bits will be identical. 


Object equality




if(tommy.equals(jakky) && tommy.hashCode() == jakky.hashCode() ){
// both references are referring to either a single object, or to tow objects that are equal
}








Two references, two objects on the heap, but the objects are considered meaningfully equivalent.
If you want to treat two different Dog objects as equal ( for example if you have decided that 2 Dog are the same if have matching name), you must override both the hashCode() and equals() method inherited from Object.

As I said above, if you don't override the hashCode() method, the default behavior is to give each object a unique hashcode value. So you must override hashCode() to be sure that two equivalent objects return the same hashcode. But you must also override equals() so that if you call it on either object passing in the other object, always return true.


How HashSet checks for duplicates : hashCode() and equals()
When you put an object into a HashSet, it uses the object's hashcode value to determine where to put the object in the Set. But it also compares the object's hashcode to the hashcode of all the objects in the HashSet, and if there is no matching hashcode, the HashSet assume that this new object is not a duplicate.
In other words, if the hashcodes are different, the HashSet assumes there is no way the objects can be equal.
So you must override hashCode() to make sure the object have the same value.
But two objects with the same hashCode() might not be equals, so if the HashSet finds a matching hashcode for two objects - one you are inserting and one already in the set -  the HashSet will then call one of the object's equals() methods to see if there hashcode matched object are really equals.
And if they are equal, the HashSet knows that the objects you are attempting to add is duplicate of something in the Set, so the add doesn't happen.

Let's see an example of HashSet for checking how it check for duplicate in the HashSet


import java.util.HashSet;  
 public class HashCodeDemo {  
  public static void main(String[] args) {  
  HashSet<Cat> hm = new HashSet<Cat>();  
  Cat c1 = new Cat("abc");  
  Cat c2 = new Cat("abcd");  
  Cat c3 = new Cat("xyz");  
  System.out.println("Adding c1");  
  System.out.println(hm.add(c1));  
  System.out.println("Adding c2");  
  System.out.println(hm.add(c2));  
  System.out.println("Adding c3");  
  System.out.println(hm.add(c3));  
  }  
 }  
 class Cat{  
  private String name;  
  Cat(String title){  
  this.name=title;  
  }  
  public String getName(){  
  return name;  
  }  
  public boolean equals(Object obj){  
  System.out.println("equals is called");  
  Cat c = (Cat)obj;  
  return name.equals(c.getName());  
  }  
  public int hashCode(){  
  System.out.println("hashcode is called");  
  return name.length();  
  }  
 }  
Sample Output
Adding c1
hashcode is called
true
Adding c2
hashcode is called
true
Adding c3
hashcode is called
equals is called
true

It's clear from the output that when it try to add c3 element in the hashSet it first called hashCode() to compare the hashcode value and on finding the same value it called equals() to check whether they are really equals or not.





If you know anyone who has started learning java, why not help them out! Just share this post with them. 
Thanks for studying today!...