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

时间:2013-12-04 12:44:14

标签: java gwt

我有一个班级

            MyData 

及其对象

             myData 

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

喜欢

           int id   

           String  name 

           String desc 

等..

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

是否可以检查这两个对象的数据是否完全相同,就像两个对象具有相同的Id,相同的名称,相同的描述...不检查此对象的每个字段..(即没有检查每个对象的id,name,desc)因为这个对象有很多字段。

我正在使用带有GWT的JAVA

我遇到了一些实现..不确定这是否有可能。无效

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

谢谢

9 个答案:

答案 0 :(得分:6)

您应该覆盖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;
}

现在您可以比较对象。就是这样。

答案 1 :(得分:3)

传统方法是覆盖equalshashCode方法。 Java标准库,例如Map s,List s,Set s使用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();
    }
    ...

答案 2 :(得分:1)

GWT对您的要求没有任何影响。

没有直接的方法。

你必须定义你的平等以检查天气是否相等。这是重写 equals()方法。

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

在做之前:Right way to implement equals contract

答案 3 :(得分:1)

与其他人一样,您应该覆盖equals()hashCode()方法。

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

答案 4 :(得分:1)

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

你说“Without checking each and every field of this object ..(i.e 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;

}

答案 5 :(得分:0)

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

答案 6 :(得分:0)

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

答案 7 :(得分:0)

覆盖hashCode()equals()方法

<强> hashCode()方法

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

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

public native int hashCode();

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

<强>等于()

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

答案 8 :(得分:0)

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

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