使用.equals()比较两个字符串返回False,但它们的字节数组相等

时间:2015-11-12 18:23:12

标签: java string byte equals

我在尝试将图像从客户端发送到服务器时遇到了一些麻烦,因为原始图像与收到的图像不同。为了找到问题,我正在逐行阅读两个图像寻找差异。当我逐行比较字符串时,对于某些使用String#equals的行(例如lineo.equals(lined)),结果为false,但是当我在控制台中打印它们时它们似乎相同,我也比较它们的字节阵列。令人惊讶的是,使用Array.equals(lineo.getBytes(),lined.getBytes())结果为true。客户端和服务器都在同一台计算机上。

请帮助我理解

  1. 我在哪里可以找到两个字符串之间的区别
  2. 为什么两种方法都要比较,返回不同的结果

    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;
    }
    

    控制台的结果是:

  3.   

    LINEO

         

    ÿÄμ}!AQa“q2?'¡#B±ÁRÑð$ 3br,

         

    内衬

         

    ÿÄμ}!AQa“q2?'¡#B±ÁRÑð$ 3br,

         

    arrayo

         

    11-1-600-751602133243554400112512304175183349656198197734113205063-111-9583566-79-632182-47-16365198114-1269

         

    arrayd

         

    11-1-600-751602133243554400112512304175183349656198197734113205063-111-9583566-79-632182-47-16365198114-1269

         

    是:真的

    请记住,我无法从输出中复制一些字符。

    此致

    安德烈斯

3 个答案:

答案 0 :(得分:5)

当您执行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()返回的字符数组。

答案 1 :(得分:0)

使用字符串比较图像可能不是解决它的最佳方式。 比较它们的字节(使用ByteArrayInputStream)。

字符串的返回字符可能不同,或者它们之间可能存在一些编码差异。

答案 2 :(得分:0)

字符串很有趣。字符串是不可变的。如果您创建两个具有相同值的字符串,则它们都指向内存中的相同引用。这称为实习。如果更新其中一个字符串,我们会在内存中获得一个新值,并且变量的指针指向新值。

当你创建两个字符串时,你要为它们分配不同的值,如果一个是编码而另一个不是,它并不关心,它实际上并不知道它们之间的区别在此刻。因此,您有两个指向不同值的字符串变量。当你执行.equals()时,你要检查两个字符串对象的等价性(它们是否指向相同的东西;否则它们不指向;因此为假)。

Here's a good article from Microsoft that explains it better than I can.