有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我有一节课

            MyData 

及其目的

             myData 

在那个类中,我的数据。。有多个字段

           int id   

           String  name 

           String desc 

等等

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

是否可以检查这两个对象的数据是否都相同,就像两个对象具有相同的Id、相同的名称、相同的描述。。。不检查此对象的每个字段。。(即不检查每个对象的id、名称、描述),因为该对象有几十个字段

我正在使用JAVA和GWT

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

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

谢谢


共 (6) 个答案

  1. # 1 楼答案

    正如其他人所说,您应该重写equals()hashCode()方法

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

  2. # 2 楼答案

    您应该重写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;
    }
    

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

  3. # 3 楼答案

    否。

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

  4. # 4 楼答案

    传统的方法是重写equalshashCode方法。Java标准库,例如Map s、List s、Set s使用equals和hashCode函数进行相等性测试。下面的代码也是空安全的

    这是您案例的代码

        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();
        }
        ...
    
  5. # 5 楼答案

    如果在添加新字段时不想再添加任何代码,可以尝试在字段上迭代

    你说“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;
    

    }

  6. # 6 楼答案

    GWT对您的需求没有影响

    没有直接的方法

    你必须定义你的相等性来检查它们是否相等。这是重写equals()方法

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

    执行之前:Right way to implement equals contract