我需要使用(Arrays.equals)比较两个DTO,它们永远不会是等号。 DTO中的数据等于我查看每个属性,有时长度等于,但Arrays.equals返回false,我尝试使用Arrays.deepEquals存在同样的问题,但在某些字段中。我在调试时发现了一些问题:
1-哈希码方法在两个DTO中都不一样 来自String类型的属性中的2-问题。
我的问题是如何测试和检测哪些属性不同。
这是我的代码快照:
Boolean isEqual = false;
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
ObjectOutputStream oStream;
ByteArrayOutputStream bStream2 = new ByteArrayOutputStream();
ObjectOutputStream oStream2;
try {
oStream = new ObjectOutputStream(bStream);
oStream.writeObject(obj1);
byte[] obj1ByteArray = bStream.toByteArray();
oStream2 = new ObjectOutputStream(bStream2);
oStream2.writeObject(obj2);
byte[] obj2ByteArray = bStream2.toByteArray();
System.out.println("Obj1>>" + obj1ByteArray.length);
System.out.println("Obj2>>" + obj2ByteArray.length);
isEqual = Arrays.equals(obj1ByteArray, obj2ByteArray);
oStream.close();
oStream2.close();
数据快照:
Length
Obj1>>709
Obj2>>709
------------------------------------------------
Object 1
com.beshara.hr.core.interfaces.web.job.shared.structure.dto.JobDTO@1ab5140
59
test_job_5555555
-100
59
1
وظيفة تجريبية 6
وظيفة تجريبية 6أخري
10
10
10.0
وظيفة تجريبية الغرض من الوظيفة 6
--------------------------------
Object 2
com.beshara.hr.core.interfaces.web.job.shared.structure.dto.JobDTO@4cfc52
59
test_job_5555555
0
59
1
وظيفة تجريبية 6
وظيفة تجريبية 6أخري
10
10
10.0
وظيفة تجريبية الغرض من الوظيفة 6
谢谢。
答案 0 :(得分:0)
如Arrays.equals(byte[],byte[])
documentation中所述:
如果两个数组包含相同数量的元素,并且两个数组中所有相应的元素对相等,则认为两个数组相等。换句话说,如果两个数组包含相同顺序的相同元素,则它们相等。
因此,如果您希望它们包含某些差异,那么您将无法成功比较两个字节数组。
如果您没有(或者不希望)控制对象的序列化方式,那么您可以使用某种Comparator<byte[]>
。
public final class MyComparator implements Comparator<byte[]> {
private static final int ATTR_START = 0;
private static final int ATTR_END = 7;
@Override
public int compare(byte[] left, byte[] right) {
if (left.length != right.length)
return left.length - right.length;
byte[] leftAttr = Arrays.copyOfRange(left, ATTR_START, ATTR_END);
byte[] rightAttr = Arrays.copyOfRange(left, ATTR_START, ATTR_END);
return Arrays.equals(leftAttr, rightAttr) ? 0 : -1;
}
}
我意识到这有点狡猾,所以这是对问题的另一种看法。
public final class MyByteArrayOutputStream extends ByteArrayOutputStream {
private static final int ATTR_START = 0;
private static final int ATTR_END = 7;
@Override
public int hashCode() {
// this can be implemented based on *your* attribute/attributes
// and its/their location in the buffer too, like in equals just below
return Arrays.hashCode(buf);
}
@Override
public boolean equals(Object object) {
boolean equals = false;
if (object instanceof MyByteArrayOutputStream) {
MyByteArrayOutputStream other = (MyByteArrayOutputStream) object;
byte[] thisAttr = Arrays.copyOfRange(buf, ATTR_START, ATTR_END);
byte[] otherAttr = Arrays.copyOfRange(other.buf, ATTR_START, ATTR_END);
if (Arrays.equals(thisAttr, otherAttr)) {
byte[] thisRest = Arrays.copyOfRange(buf, ATTR_END, buf.length);
byte[] otherRest = Arrays.copyOfRange(other.buf, ATTR_END, buf.length);
equals = Arrays.equals(thisRest, otherRest);
}
}
return equals;
}
}
子类ByteArrayOutputStream
并实现自定义等于逻辑。
答案 1 :(得分:0)
一些评论但不是解决方案:
与您问题的标题相反,Arrays.equals
不是您的问题,而是ObjectOutputStream
的输出。甚至可能不是这样 - 它可能是Unicode编码问题(见下文)。
请提供short, self contained and correct example。您的代码错过了真实的输入数据。这与下一点相加:
StackOverflow的大多数读者无法做任何西班牙语,法国语,德语...脚本的偶然特征。更别说完整的阿拉伯语单词了。这大大减少了想要大量思考问题的人数。
最后解决问题本身:由于Unicode允许字符组合的方式,可以以相同的方式显示两个不同的Unicode字符串。所以一般的建议是:尽可能地解决你的问题。
String.equals
进行比较。 false
但以相同方式显示的每一对:使用java.text.Normailzer
和NFC
将其提供给NFKC
并再次比较结果如果此程序无法解决您的问题或缩小您的问题范围,那么请通过编辑您的问题来提供检查结果。
哦,我差点忘了:你说过
我需要使用两个DTO进行比较...
你应该考虑你真正想要实现的目标,然后决定 如何做到这一点。如果要比较字节,请使用Arrays.equals
。如果你想比较DTO,那么通过比较DTO中的每个字段来构建你自己的比较方法,在这里进行任何花哨的“规范化”。可以帮助您的工具可能是Apache EqualsBuilder。