4

我想编写一个 java 程序,它必须找到不同实例的两个对象之间的差异。我已经使用 equals() 和比较器实现了它。但是在这里我想找到差异并且必须以日志格式显示。

我的程序如下:

public class A implements Comparator<A>{

private int id1, id2;

/* setters and getters for id1 and id2 */

     public boolean equals(Object arg0) {
    if (this.getClass() != arg0.getClass()) {
        return false;
        }

        if (((A) arg0).getId1() == this.id1 && ((A) arg0).getId2() == this.id2) {
        return true;
        }

        return false;
     }

 public static void main(String args[]) {

    A obj1 = new A();
    obj1.id1 = 10;
    obj1.id2 = 20;

    A obj2 = new A();
    obj2.id1 = 30;
    obj2.id2 = 20;

    /*
     * equals comparison
     */

    if (obj1.equals(obj2)) {
        System.out.println("EQUALS");
    } else {
        System.out.println("NOT EQUALS");
    }

}

请任何人告诉我如何找到差异并以日志格式显示。

谢谢。

4

5 回答 5

2

要实现Comparator<A>你需要一个方法public int compare(A o1, A o2)。这是这种实现的一个例子:

@Override
public int compare(A o1, A o2) {
    if (o1 == o2) {
        return 0;
    } else if (o1 == null) {
        return -1;
    } else if (o2 == null) {
        return 1;
    }
    if (o1.getId1() != o2.getId1()) {
        return o1.getId1() - o2.getId1();
    } else {
        return o1.getId2() - o2.getId2();
    }
}

然后你可以像这样使用它:

    if (obj1.compare(obj1, obj2) == 0) {
        System.out.println("EQUALS");
    } else {
        System.out.println("NOT EQUALS");
    }

让另一个类实现Comparator<A>,而不是把它放在A自己里面可能更常见。

于 2012-07-06T06:47:29.477 回答
1

您可以使用 javaReflection来比较两个相同类型的 bean,它们具有用于所有比较属性的 getter。

public static void compareBeans(Object bean1, Object bean2, String... propertyNames)
          throws IntrospectionException,
          IllegalAccessException, InvocationTargetException {
        Set<String> names = new HashSet<String>(Arrays
            .asList(propertyNames));
        BeanInfo beanInfo = Introspector.getBeanInfo(bean1
            .getClass());
        for (PropertyDescriptor prop : beanInfo
            .getPropertyDescriptors()) {
          if (names.remove(prop.getName())) {
            Method getter = prop.getReadMethod();
            Object value1 = getter.invoke(bean1);
            Object value2 = getter.invoke(bean2);
            if (value1 == value2
                || (value1 != null && value1.equals(value2))) {
              continue;
            }

            System.out.println("Property = "+prop.getName() +" Value of been1 ="+value1 +" : Value of bean2 ="+value2);
          }
        }
      }

用法:

Student如果我比较两个具有两个属性nameage类的豆类

BeanComparator.compareBeans(new Student("Amita", 21), new Student("Amit", 23) , props);

输出:

Property = age Value of been1 =21 : Value of bean2 =23
Property = name Value of been1 =Amita : Value of bean2 =Amit
于 2012-07-06T07:37:13.447 回答
0

您可以更改equals方法并比较每个属性。对于您进行的每次比较,您都会记录您的结果。像这样的东西应该起作用:

@Override
public boolean equals(Object arg0) {
    if (this.getClass() != arg0.getClass()) {
        return false;
    }

    boolean same = true;
    //LOG: Comparing ((A) arg0).getId1() with this.id1
    if (((A) arg0).getId1() == this.id1) {
        //LOG: Property Id1 is the same for both: Value of Id1 = this.id1        
    }
    else {
        //LOG: Property Id1 is not the same. Source Id1 = ((A) arg0).getId1() , target Id1 = this.id1
        same = false;
    }

    if (((A) arg0).getId2() == this.id2) {
        //LOG: Property Id2 is the same for both: Value of Id2 = this.id2        
    }

    else {
        //LOG: Property Id2 is not the same. Source Id2 = (((A) arg0).getId2(), target Id2 = this.id2
        same = false;
    }

    //
    return same;
}

编辑:当您说您自己的比较器时,我并不完全理解您的意思。如果您想自己进行比较,可以执行以下操作:

public boolean areTheSame(Object arg1, Object arg2)
{
    if (arg1.getClass() != arg0.getClass()) {
        return false;
    }

    boolean same = true;
    //LOG: Comparing ((A) arg0).getId1() with arg1.id1
    if (((A) arg0).getId1() == arg1.id1) {
        //LOG: Property Id1 is the same for both: Value of Id1 = arg1.id1        
    }
    else {
        //LOG: Property Id1 is not the same. Source Id1 = ((A) arg0).getId1() , target Id1 = arg1.id1
        same = false;
    }

    if (((A) arg0).getId2() == arg1.id2) {
        //LOG: Property Id2 is the same for both: Value of Id2 = this.id2        
    }

    else {
        //LOG: Property Id2 is not the same. Source Id2 = (((A) arg0).getId2(), target Id2 = arg1.id2
        same = false;
    }

    //
    return same;
}

你可以把它放在你的主类中并调用它而不是这些行:

if (obj1.equals(obj2)) {
    System.out.println("EQUALS");
} else {
    System.out.println("NOT EQUALS");
}

所以你只需这样做:

if (areTheSame(obj1, obj2)) 
{
    System.out.println("They are equal");
}
else
{
    System.out.println("They are not equal");
}
于 2012-07-06T06:03:23.737 回答
0

您可以使用Apache Commons EqualsBuilder来生成您的equals()方法

给定一个类:

public class Person {
    private long id;
    private String firstName;
    private String lastName;
}

你的 equals 方法看起来像

public boolean equals(Object object) {
    if (!(object instanceof Person)) {
        return false;
    }
    Person rhs = (Person) object;
    return new EqualsBuilder()
        .appendSuper(super.equals(object))
        .append(firstName, rhs.firstName)
        .append(lastName, rhs.lastName)
        .isEquals();
}

或者,如果您想使用反射来执行此操作

public boolean equals(Object o) {
   return EqualsBuilder.reflectionEquals(this, o);
}
于 2013-07-29T08:52:07.860 回答
0

您可以使用开源工具 javers - https://github.com/javers/javers。在 Javers 中,您可以找到返回 Diff 的方法 compare(Object one, Object another)。Diff 包含一个更改列表(引用添加、属性更改等)。

于 2014-04-05T13:15:44.780 回答