简体   繁体   中英

How to compare the data of two same Objects in Java

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 ..(ie 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

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.

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();
    }
    ...

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

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.

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 ..(ie 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;

}

No.

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

覆盖MyData对象的equals方法,并独立检查字段。

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.

Serialize your objects and compare the results!

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM