使用 .equals() returns False 比较两个字符串,但它们的字节数组相等
Comparing two Strings using .equals() returns False, but their byte arrays are equal
我在尝试将图像从客户端发送到服务器时遇到了一些麻烦,因为原始图像与接收到的图像不同。为了找到问题所在,我正在逐行阅读两个图像以寻找差异。当我逐行比较字符串时,对于某些使用 String#equals 的行(例如 lineo.equals(lined)),结果是错误的,但是当我在控制台中打印它们时它们看起来是一样的,我也比较他们的字节数组。令人惊讶的是,使用 Array.equals(lineo.getBytes(), lined.getBytes()) 结果是正确的。客户端和服务器都在同一台计算机上。
请帮助我理解
- 我在哪里可以找到两个字符串之间的区别
为什么两种方法比较,returns不同的结果
private void compareImages() throws IOException {
File dest = new File("C:\TempFiles\" + fileName);
File orig = new File("C:\Users\Andres\Desktop\B&N\" + fileName);
BufferedReader bro = new BufferedReader(new FileReader(orig));
BufferedReader brd = new BufferedReader(new FileReader(dest));
String lineo = bro.readLine();
String lined = brd.readLine();
System.out.println("Ready to read");
while (lineo!= null && lined!= null) {
if(!lined.equals(lineo))
{
System.out.println("lineo");
System.out.println(lineo);
System.out.println("lined");
System.out.println(lined);
System.out.println("arrayo");
System.out.println(printArray(lineo.getBytes()));
System.out.println("arrayd");
System.out.println(printArray(lined.getBytes()));
System.out.println("Are: " + Arrays.equals(lined.getBytes(), lineo.getBytes()));
break;
}
lineo = bro.readLine();
lined = brd.readLine();
}
bro.close();
brd.close();
}
public String strArray(byte[] array){
String toRet = "";
for (byte b : array) {
toRet += b;
}
return toRet;
}
控制台的结果是:
lineo
ÿÄ µ }!AQa"q2?‘¡#B±ÁRÑðbr‚
lined
ÿÄ µ }!AQa"q2?‘¡#B±ÁRÑðbr‚
arrayo
11-1-600-751602133243554400112512304175183349656198197734113205063-111-9583566-79-632182-47-16365198114-1269
arrayd
11-1-600-751602133243554400112512304175183349656198197734113205063-111-9583566-79-632182-47-16365198114-1269
Are: true
请注意,我无法从输出中复制某些字符。
此致,
安德烈斯
使用字符串比较图像可能不是最好的方法。
比较它们的字节(使用 ByteArrayInputStream)。
字符串的 return 字符可能不同,或者它们之间可能存在一些编码差异。
当您执行 getBytes()
.
时,不相等的字符串不必生成不同的数组
结果取决于平台的默认字符集,但是当我运行下面的代码
String str1 = "?";
byte[] arr1 = str1.getBytes();
String str2 = "\u0080";
byte[] arr2 = str2.getBytes();
System.out.println(str1.equals(str2));
System.out.println(Arrays.equals(arr1, arr2));
我看到的输出是
false
true
我不知道这里到底发生了什么,但看起来某些控制字符被视为 '?'
。
理解字符串不同的正确方法是比较toCharArray()
.
返回的字符数组
字符串是很有趣的东西。字符串是不可变的。如果您创建两个具有相同值的字符串,它们都指向内存中的相同引用。这叫做实习。如果您更新其中一个字符串,我们会在内存中获得一个新值,并且您的变量指针指向新值。
当您创建两个字符串时,您为它们分配了不同的值,它不关心一个是否已编码而另一个未编码,此时它实际上并不知道差异。因此,您有两个指向不同值的字符串变量。当您执行 .equals() 时,您正在检查两个字符串对象的等效性(它们是否指向同一事物;不,它们不指向;因此为假)。
Here's a good article from Microsoft that explains it better than I can.
我在尝试将图像从客户端发送到服务器时遇到了一些麻烦,因为原始图像与接收到的图像不同。为了找到问题所在,我正在逐行阅读两个图像以寻找差异。当我逐行比较字符串时,对于某些使用 String#equals 的行(例如 lineo.equals(lined)),结果是错误的,但是当我在控制台中打印它们时它们看起来是一样的,我也比较他们的字节数组。令人惊讶的是,使用 Array.equals(lineo.getBytes(), lined.getBytes()) 结果是正确的。客户端和服务器都在同一台计算机上。
请帮助我理解
- 我在哪里可以找到两个字符串之间的区别
为什么两种方法比较,returns不同的结果
private void compareImages() throws IOException { File dest = new File("C:\TempFiles\" + fileName); File orig = new File("C:\Users\Andres\Desktop\B&N\" + fileName); BufferedReader bro = new BufferedReader(new FileReader(orig)); BufferedReader brd = new BufferedReader(new FileReader(dest)); String lineo = bro.readLine(); String lined = brd.readLine(); System.out.println("Ready to read"); while (lineo!= null && lined!= null) { if(!lined.equals(lineo)) { System.out.println("lineo"); System.out.println(lineo); System.out.println("lined"); System.out.println(lined); System.out.println("arrayo"); System.out.println(printArray(lineo.getBytes())); System.out.println("arrayd"); System.out.println(printArray(lined.getBytes())); System.out.println("Are: " + Arrays.equals(lined.getBytes(), lineo.getBytes())); break; } lineo = bro.readLine(); lined = brd.readLine(); } bro.close(); brd.close(); } public String strArray(byte[] array){ String toRet = ""; for (byte b : array) { toRet += b; } return toRet; }
控制台的结果是:
lineo
ÿÄ µ }!AQa"q2?‘¡#B±ÁRÑðbr‚
lined
ÿÄ µ }!AQa"q2?‘¡#B±ÁRÑðbr‚
arrayo
11-1-600-751602133243554400112512304175183349656198197734113205063-111-9583566-79-632182-47-16365198114-1269
arrayd
11-1-600-751602133243554400112512304175183349656198197734113205063-111-9583566-79-632182-47-16365198114-1269
Are: true
请注意,我无法从输出中复制某些字符。
此致,
安德烈斯
使用字符串比较图像可能不是最好的方法。 比较它们的字节(使用 ByteArrayInputStream)。
字符串的 return 字符可能不同,或者它们之间可能存在一些编码差异。
当您执行 getBytes()
.
结果取决于平台的默认字符集,但是当我运行下面的代码
String str1 = "?";
byte[] arr1 = str1.getBytes();
String str2 = "\u0080";
byte[] arr2 = str2.getBytes();
System.out.println(str1.equals(str2));
System.out.println(Arrays.equals(arr1, arr2));
我看到的输出是
false
true
我不知道这里到底发生了什么,但看起来某些控制字符被视为 '?'
。
理解字符串不同的正确方法是比较toCharArray()
.
字符串是很有趣的东西。字符串是不可变的。如果您创建两个具有相同值的字符串,它们都指向内存中的相同引用。这叫做实习。如果您更新其中一个字符串,我们会在内存中获得一个新值,并且您的变量指针指向新值。
当您创建两个字符串时,您为它们分配了不同的值,它不关心一个是否已编码而另一个未编码,此时它实际上并不知道差异。因此,您有两个指向不同值的字符串变量。当您执行 .equals() 时,您正在检查两个字符串对象的等效性(它们是否指向同一事物;不,它们不指向;因此为假)。
Here's a good article from Microsoft that explains it better than I can.