使用 Arrays.equals 比较两个 dto 的 java 字节数组
我有两个 DTO 需要使用 (Arrays.equals) 进行比较,它们永远不会是 equals 。当我查看每个属性时,两个 DTO 中的数据都是相等的,有时它的长度相等,但 Arrays.equals 返回 false,我尝试使用 Arrays.deepEquals 存在相同的问题,但在某些字段中。我在调试时发现了一些问题:
1-两个 DTO 中的哈希码方法不一样。
2- String 类型属性中的问题。
我的问题是如何测试和检测哪些属性不同。
这是我的代码快照:
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
谢谢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一些评论,但不是解决方案:
与您的问题标题相反,不是
Arrays.equals
是您的问题,而是ObjectOutputStream
的输出。即使这可能不是真的 - 它可能是一个 Unicode 编码问题(见下文)。请提供简短、独立且正确的示例。您的代码丢失了真实的输入数据。这是与下一点相加的:
大多数 StackOverflow 读者都无法执行西班牙语、法语、德语等脚本中偶尔出现的特殊字符的任何操作。更不用说完整的阿拉伯语单词了。这大大减少了想要考虑你的问题的人数。
最后是问题本身:由于 Unicode 允许字符组合的方式,两个不同的 Unicode 字符串可以以相同的方式显示。所以一般性的建议是:尽可能地简化你的问题。
String.equals
比较 DTO 中的每个字符串对。false
但以相同方式显示的每一对:使用NFC
将它们馈送到java.text.Normailzer
NFKC
并再次比较结果。如果此过程无法解决您的问题或缩小问题的范围,那么仍然可以通过编辑问题来提供检查结果。
哦,我差点忘了:你说过
您应该考虑您真正想要实现的目标,然后决定如何做到这一点。如果要比较字节,请使用 Arrays.equals。如果您想比较 DTO,则可以通过比较 DTO 中的每个字段来构建您自己的比较方法,并在此处执行任何奇特的“标准化”。一个可以帮助您的工具可能是 Apache EqualsBuilder。
Some remarks but not a sollution:
Contrary to the title of your question not
Arrays.equals
is your problem but the output ofObjectOutputStream
. And even that might not be true - it might be an Unicode encoding problem (see below).Please provides a short, self contained and correct example. Your code misses the real input data. This is adds up with the next point:
Most readers of StackOverflow can't do anything the occasionally special character of spanish, france, german ... scripts. Let alone complete arabic words. This decimates the number of people who want to think about your problem considerably.
Finally something to the problem itself: Two different Unicode strings can be displayed in the same way due to the way Unicode allows combinations of characters. So a general advice is: Boil down your problem as far as possible.
String.equals
.false
but is displayed in the same way must be examined further: Feed them tojava.text.Normailzer
using bothNFC
andNFKC
and compare the results again.If this procedure does not work to solve your problem or to narrow downs your problem, then nevertheless provide the results from your examination by editing your question.
Oh, I nearly forgot: You stated
You should think about what you really want to achieve and then decide how to do that. If you want to compare bytes, use the
Arrays.equals
. If you want to compare DTOs, then build your own compare method by comparing each field in the DTOs doing any fancy "normalization" here. A tool to help you with that might be Apache EqualsBuilder.如
Arrays.equals(byte[],byte[])
文档:因此,如果您希望字节数组包含一些差异,则您将无法成功比较它们。
如果您没有(或不想)控制对象的序列化方式,那么您可能可以使用某种
Comparator
。我意识到这有点狡猾,所以这是这个问题的另一种看法。
子类 ByteArrayOutputStream 并实现您的自定义等于逻辑。
As stated in
Arrays.equals(byte[],byte[])
documentation:So, you won't be able two compare your byte arrays successfully if you expect them to contain some differences.
If you don't have (or don't want to have) control over how your objects are getting serialized, then you can probably use some sort of
Comparator<byte[]>
.I realize that this is a bit dodgy, so here is another take on the problem.
Subclass
ByteArrayOutputStream
and implement your custom equals logic.