Friday, June 30, 2017

How to Compare Two Objects with the equals Method in Java? What is the differents between == and equals()?

Difference between == and equals() in java.

  •  == check object reference are same or not.It check only the objects are same, not equality of object.
  • equals() check reference values are same are not.Its checks the equality of the object fields. If you want to check the object equality we need to override the equals(). 
Example:

    //Value stored in String Pool
   String l_sValue = "Equals";

    //Reference stored in heap memory.
    String l_sSecValue = new String("Equals");

   //Both objects having same value. The values are equals.So its returns true.
    if(l.equals(k)) Output: return true;

   //Both are addressing different object, returns false.
    if((l == k)) Output: return false;

/**
 * @author palrajb
 *
 */
public class Test {

    private String name;
    private int age;
    private int marks;

    public Test() {
    }

    public Test(String name, int age, int marks) {
        this.name = name;
        this.age = age;
        this.marks = marks;
    }

    public void setMarks(int marks) {
        this.marks = marks;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {


        Test t = new Test("1", 1, 1);// Create the object t with three parameter constructor.

        Test t1 = (Test) t;
// Addressing same reference.

        t1.setMarks(2);
// Changes on t1 directly affect t. Because t1 is addressing t reference.                      
// Here t and new object having same values, but we are not override the equals() to equals the fields of Test class. So passing reference are different. 

       System.out.println(t.equals(new Test("1", 1, 1)));Output : false
// Here we are t and t1 are addressing single object t.So their address  and fields are same, returns  true.
      System.out.println(t.equals(t1)); Output : true
// Here we are t and t1 are addressing single object t. As per state check only the objects are same, return true.
      System.out.println(t == t1);Output : true




if you want to make t.equals(new Test("1",1,1)) true, we need to override the equals()

@Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Test other = (Test) obj;
        if (age != other.age)
//Here checking the age of t and new Test("1",1,1) object age is not same.
            return false;
        if (name == null) {
//Null check for name, because we have setter method for name variable.
            if (other.name != null)
//Same null check for new Test("1",1,1).
                return false;
        } else if (!name.equals(other.name))
//Here checking the name of t and new Test("1",1,1) object name is not same.
            return false;
        return true;
    }


After the equals() implementation, now execute the

System.out.println(t.equals(new Test("1", 1, 1)));//Output: true. Because we customized the equals method as we want. We just compare the age and name variable only, we are not consider the marks variable for equals() implementation so changes the value by using
t1.setMarks(2); not affect anything on the equality.


Meanwhile we know that if we override the equals() then we need to override hashCode().

@Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }


Do you feel we would missed any variable in equals() and hashCode().
    Yes, the marks variable is missing. Key to override the equals() and hashCode() is the filed used in equals() must be used hashCode implementation.





Thursday, June 29, 2017

Java is pass-by-value or pass-by-reference?

Java is strictly pass-by-value. 

Then the next question is how it is pass-by-value ?
   
 Here the explanation from SCJP.


"Java is actually pass-by-value for all variables running within a single VM. Pass-by-value means pass-by-variable-value. And that means, pass-by-copy-ofthe-variable,which means pass-by-copy-of-the-bits-in-the-variable"


Here we have example for passing variable and passing reference.


package com.test.java;

/**
 * @author palrajb
 *
 */
public class Test {

    private String name;
    private int age;
    private int marks;

    public Test() {
    }

    public Test(String name, int age, int marks) {
        this.name = name;
        this.age = age;
        this.marks = marks;
    }

    public void setMarks(int marks) {
        this.marks = marks;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {

        Test l_objTest = new Test("A", 1, 12);
        int l_iIntValue = 1;
        System.out.println("Mark Before invoke : " + l_objTest.marks + " IntValue :" + l_iIntValue);
      
  //Output:Mark Before invoke : 12 IntValue :1
        doTest(l_objTest, l_iIntValue);
//Here we are passing reference and variable as parameter.
        System.out.println("Mark After invoke : " + l_objTest.marks    + " IntValue :" + l_iIntValue);
       
//Output:Mark After invoke : 14 IntValue :1
    }





Here we got the copy of calling method reference variable. We change the p_iIntValue +1, but the called method can't change the caller's variable.So when we print this from main method its still 1. For p_objTest.setMarks(14) will change the caller l_objTest object marks to 14,because the called method can change the object the variable referred.

     static void doTest(Test p_objTest, int p_iIntValue)
    {
        p_iIntValue = p_iIntValue + 1;
//Using same reference but in different address.So increment happens only on newly created address not on old one.The called method can't change the caller's variable
        p_objTest.setMarks(14);
//called method can change the object the variable referred.
        p_objTest = new Test("B", 2, 13);
//we using same reference but in different address. So the caller reference not going to change anyway.
        p_objTest.setMarks(15);//
change the mark value in newly referenced object.
    }

}

Tuesday, June 27, 2017

What happen when you are not print or throw the exception in catch block?

try block-- Here the actual logic and implementation. 
catch block--If try block may have come error in the logic or implementation we can catch the error.Here we can catch the try block error.Catching error is just do print the stack trace of the what error is occurred.

Now consider we are trying below condition, its just do create exception in try block,do not bother about implementation in try block.

package com.test.java;

import java.util.Scanner;

/**
 * @author boomiraj
 *
 */
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Scanner l_objInput = new Scanner(System.in);
        System.out.println("Please Enter the value : ");
        convertStringToInt(l_objInput.next());
    }

    private static void convertStringToInt(String p_sValue) {
        int i = 0;
        try {

            i = Integer.parseInt(p_sValue);
            if (i < 100) {
                i = i + 1;
            } else {
                i = i - 1;
            }

        } catch (NumberFormatException e) {
         }
        System.out.println("Converted into interger from string : " + i);
    }

}


In public method we are calling convertStringToInt(String) to convert given String Value to Int.
   
    We are getting input from user, so user can enter any possible combination of input like
    Alphabet
    Alphanumeric
    Number
    Special character
   
    If user enters only Number, its not problem we can get the output without error.
    But if he tries any other combination then there is possibility to have an error.
    In this scenario we are catch the exception, but in the catch block we don't have any print stack trace or print log.
    then the user does not know that the entered values are not able to convert into Int. But he always get some output.

    This may cause the some blocker issue in your project.

  catch (NumberFormatException e) {
            System.err.println("Cannot convert the value '" + p_sValue
                    + "' to integer");
        }


So always print something into your catch block.

Monday, June 19, 2017

Change the execution value by the time of debug in eclipse.

If you want to change the value of the primitive instance we can change by using variables tab.
or else we can change the value by using "Display" window.

In Variable tab we can see the all the object and instance of the current thread.
Press (Cntl+f) and type the variable name you want to change the value.
Then click on the right side of the variable and change the value.
Note : By this way we can only change the value of primitive data type. We cannot change the object reference.


In Display window you can write the value to be change and select the line and press (ctrl+u).
If I have the String l_sValue = "World"; if i want to change the String l_sValue = "Change the World";
l_sValue = "Change the World"; copy this line and press (ctrl+u)
Note : By this we can do change both primitive and object reference.