繁体   English   中英

如何在Java中比较两个相同对象的数据

[英]How to compare the data of two same Objects in Java

我有一堂课

            MyData 

及其对象

             myData 

在该类MyData ..中,有多个字段

喜欢

           int id   

           String  name 

           String desc 

等..

现在我有两个此类的对象..

是否有可能检查这两个对象的数据是否全部相同,就像两个对象都具有相同的ID,相同的名称,相同的Desc ...而不检查此对象的每个字段..(即,不检查每个对象本身的id,name,desc)因为此对象有数十个字段。

我在GWT中使用JAVA

我遇到了一些实现..不确定这是否有可能.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;
        }
    }

谢谢

您应该重写hashCode()equals()方法。 您可以从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;
}

现在您可以比较对象。 而已。

常规方法是重写equalshashCode方法。 Java标准库(例如Map,List,Set)使用equals和hashCode函数进行相等性测试。 下面的代码也是null安全的;

这是您的情况的代码;

    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;
    }
}

您可以通过以下方式测试是否相等:

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

但是,如果不允许您逐字段进行比较,则可以使用字节数组,则无需将它们转换为字符串。

    .....
    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对您的要求没有任何影响。

没有直接的方法。

您必须定义相等性以检查天气是否相等。 那是重写equals()方法。

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

在做之前: 实施平等合同的正确方法

就像其他所有人都说的那样,您应该覆盖equals()hashCode()方法。

请注意,您不必手动执行此操作。 在Eclipse中,您只需单击Source/generate hashCode() and equals()为您完成工作。 我确信其他IDE也具有类似的功能。

如果您不想在添加新字段时添加更多代码,则可以尝试遍历字段。

您说:“ Without checking each and every field of this object ..(ie without checking the id,name,desc of Each object myself) ”,我无法弄清楚您是否不想检查每个字段的相等性,或者不想为每个字段写检查是否相等。 我假设使用后者,因为您试图通过使用按字节检查来添加相等比较方法。

无论如何,下面是检查每个字段的代码。 您可以复制/粘贴到任何对象。 如果将来希望检查某些字段,而又不想检查某些字段,则可以使用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;

}

没有。

您必须重写equals()方法并比较其中的对象。

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

覆盖hashCode()equals()方法

hashCode()

此方法提供对象的has代码。

基本上,Object提供的hashCode()的默认实现是通过将内存地址映射到整数值来派生的。 如果查看Object类的源代码,则将为hashCode找到以下代码。

public native int hashCode();

它表明hashCode是本机实现,可以在一定程度上提供内存地址。 但是,可以在实现类中覆盖hashCode方法。

等于()

此方法用于在两个对象之间进行相等比较。 Java有两种类型的比较。 一种是使用“ = =”运算符,另一种是“ equals()”。 我希望您知道这两者之间的区别。 更具体地说, .equals()表示等价关系。 因此,从广义上讲,您说两个对象相等,它们满足equals()条件。

序列化您的对象并比较结果!

您应该明智地选择序列化方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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