我有一个可序列化的课程,我想比较一下。它包含许多字段,将来可能会改变很多次。实现这样的平等有什么缺点:
public class ProbierKlasse implements Serializable{
private static final long serialVersionUID = -7996094306948821373L;
private File dir = new File("dir");
private File subDir = new File(dir, "subDir");
private File file = new File(dir, "file");
public static void main(String[] args) throws IOException {
ProbierKlasse pk = new ProbierKlasse();
ProbierKlasse pk1 = new ProbierKlasse();
System.out.println(pk.equals(pk1)); //prints true
pk1.subDir = new File(pk1.dir, "anotherDir");
System.out.println(pk.equals(pk1)); //prints false
}
@Override
public boolean equals(Object obj) {
byte[] thisBytes = getByteArray(this);
byte[] objBytes = getByteArray((ProbierKlasse)obj);
return Arrays.equals(thisBytes, objBytes);
}
private byte[] getByteArray(Serializable obj){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
} catch (IOException e) {
throw new RuntimeException(e);
}
return baos.toByteArray();
}
}
我可以将性能视为一个问题,但在这种情况下它并不那么重要。它有一个很大的优势,如果我添加新字段,我就不必调整它。
提前致谢,请不要讨厌我。
答案 0 :(得分:1)
因此,您基本上是在equals
中编写对象,然后比较这些字节数组。
性能可能是一个缺点,但说实话,这取决于您的对象的次数和大小。如果它每秒钟有两个或三个对象,你应该没问题,但如果每秒几千,这可能需要一些时间。此外,如果您的对象引用其他对象,则会占用更多时间。
请注意不要进行循环引用(但我想只要序列化工作,curl -X GET -u user:password $URL
就可以了)。例如:如果A引用B和B引用A。
无论如何,如果你想要更好的自动比较系统,你应该检查“java中的反射”。这是一个令人感兴趣的事情。此外,如果你想要一个已经可以使用它的比较器,apache有一个非常好的比较器(包是apche utils或其他东西)。
检查一下:Is there a Java reflection utility to do a deep comparison of two objects?(这是为了深入比较,但也应该适合你)和这个:Comparing field values using reflection