0

I have a class

            MyData 

and its object

             myData 

In that Class MyData .. there are multiple fields

like

           int id   

           String  name 

           String desc 

etc ..

Now i have two objects of this class ..

Is it possible to check that if the data of these two object are all the same , Like both objects have the same Id ,same Name ,same Desc ... Without checking each and every field of this object ..(i.e without checking the id,name,desc of Each object myself) As there are dozens of fields of this object .

I am using JAVA with GWT

Some implementation i came across.. Not sure if this is some thing possible .valid

    private static String oldSequence = "";

    boolean changed(TestSequence sequence) {
        String newSequence = serializeToString(sequence);
        boolean changed = !newSequence.equals(oldSequence);
        oldSequence = newSequence;
        return changed;


    }

    private static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    private static String serializeToString(Object obj) {
        try {
            return new String(serialize(obj));
        } catch (Exception ex) {
            return "" + ex;
        }
    }

Thanks

1
  • 1
    your edit has completely changed the question, better to have asked as a different question.
    – hevi
    Commented Dec 4, 2013 at 13:00

9 Answers 9

6

You should override hashCode() and equals() method. you can generate these from IDE.

 @Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof MyData)) return false;

    MyData myData = (MyData) o;

    if (id != myData.id) return false;
    if (!desc.equals(myData.desc)) return false;
    if (!name.equals(myData.name)) return false;

    return true;
}

@Override
public int hashCode() {
    int result = id;
    result = 31 * result + name.hashCode();
    result = 31 * result + desc.hashCode();
    return result;
}

Now you can compare the objects. That's it.

3
  • It is not the safe implementation. what if and of the strings is null?!
    – hevi
    Commented Dec 4, 2013 at 12:56
  • @hevi If some one want to compare empty object here. you can use some validation. BTW what is the reason to compare an empty object here? Commented Dec 4, 2013 at 13:01
  • @Ruhchira some fields might be null intentionally which breaks your solution.
    – hevi
    Commented Dec 4, 2013 at 13:05
3

Conventional way is to override equals and hashCode methods. Java standard libraries, for instance Map s, List s, Set s use the equals and hashCode functions for equality testing. The code below also null-safe;

Here is the code for your case;

    public class MyData {
    int id;

    String name;

    String desc;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MyData myData = (MyData) o;

        if (id != myData.id) return false;
        if (desc != null ? !desc.equals(myData.desc) : myData.desc != null) return false;
        if (name != null ? !name.equals(myData.name) : myData.name != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (name != null ? name.hashCode() : 0);
        result = 31 * result + (desc != null ? desc.hashCode() : 0);
        return result;
    }
}

and you can test the equality by;

....
Mydata d1 = new...
Mydata d2 = new...
boolean areTheyEqual = d1.equals(d2);

However if you are not allowed to make a compare field by field then you can use byte arrays, there is no need to convert them to strings.

    .....
    public boolean equals(Object other){
        if (this == other) return true;
        if (other == null || getClass() != other.getClass()) return false;
        byte[] bytesThis = serialize(this);
        byte[] bytesOther = serialize(other);
        if(bytesOther.length != bytesThis.length) return false;
        return Arrays.equals(bytesThis, bytesOther);
    }

    public static byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }
    ...
1

GWT doesn't make a difference to your requirement.

There is no direct way.

You have to define your equality to check weather they are equal or not. That is overriding equals() method.

@Override
public boolean equals(Object obj) { ...

Before doing:Right way to implement equals contract

1

Like everyone else is saying, you should override the equals() and hashCode() methods.

Note that you don't have to do this manually. In Eclipse you can simply click on Source/generate hashCode() and equals() and it will do the work for you. I am sure other IDEs have similar feature as well.

1

If you don't want to add any more code when you add a new field, you can try iterating over fields.

You said "Without checking each and every field of this object ..(i.e without checking the id,name,desc of Each object myself) ", I couldn't figure out whether you don't want to check for each field for equality, or don't want to WRITE a check for each field for equality. I assumed the latter since you tried to add an equality comparison method by using bytewise checks.

Anyways, the code to check each field follows. You can copy/paste to any object. If, in the future, you want some fields to be checked and some not, you can use annotations.

 @Override
 public boolean equals(Object o) {
     if (this == o) return true;
     if (o == null || getClass() != o.getClass()) return false;

     MyData myData = (MyData) o;

     Field[] fields = this.getClass().getDeclaredFields();
     for(Field field:fields){
         Object o1 = null;
         Object o2  = null;
         try {
             o1 = field.get(this);
             o2 = field.get(o);
         } catch (IllegalAccessException e) {
           return false;
         }
         if(o1 == null && o2 != null) return false;
         if(o2 == null && o1 != null) return false;
         if(o2 == null && o1 == null) continue;

         if(!o2.equals(o1)) return false;
     }

     return true;

}

1
  • This implementation is partially correct; consider having another class derived from this class with some additional fields, in this case it won't correctly work :)
    – hevi
    Commented Dec 4, 2013 at 14:06
0

No.

You have to override the equals() method and compare the objects in that.

0

Override the equals method of the object in MyData and check the fields independently.

0

Serialize your objects and compare the results!

You just should be wise in selection of your serialization method.

1
  • Can you give a small example of this please
    – junaidp
    Commented Dec 4, 2013 at 13:03
0

Override hashCode() and equals() methods

hashCode()

This method provides the has code of an object.

Basically the default implementation of hashCode() provided by Object is derived by mapping the memory address to an integer value. If look into the source of Object class , you will find the following code for the hashCode.

public native int hashCode();

It indicates that hashCode is the native implementation which provides the memory address to a certain extent. However it is possible to override the hashCode method in your implementation class.

equals()

This method is used to make equal comparison between two objects. There are two types of comparisons in Java. One is using “= =” operator and another is “equals()”. I hope that you know the difference between this two. More specifically the .equals() refers to equivalence relations. So in broad sense you say that two objects are equivalent they satisfy the equals() condition.

Not the answer you're looking for? Browse other questions tagged or ask your own question.