equal()和equalsIgnoreCase()对于相等的字符串返回false

时间:2010-11-18 01:04:00

标签: java string string-comparison

我在mac上使用eclipse IDE(版本:3.4.2),我遇到了以下问题。

当使用equal()或equalsIgnoreCase()方法比较字符串时,即使字符串相等,我也会收到false。例如,即使值[0] =“debug_mode”

if (values[0].equalsIgnoreCase("debug_mode")) debug_mode = true;

是以下循环的一部分:

String value = dis.readLine();
String values[] = value.trim().split("=");
if (values.length >= 2)
{
    Config.prnt_dbg_msg(values[0] + "\t" + values[1]);
    if (values[0].equalsIgnoreCase("debug_mode")) 
        debug_mode = isTrue(values[1]);
    if (values[0].equalsIgnoreCase("debug_query_parsing")) 
        debug_query_parsing = isTrue(values[1]);
    if (values[0].equalsIgnoreCase("username")) 
        Connection_Manager.alterAccessParameters(values[1], null, null);
    if (values[0].equalsIgnoreCase("password")) 
        Connection_Manager.alterAccessParameters(null, values[1], null);
if (values[0].equalsIgnoreCase("database")) 
        Connection_Manager.alterAccessParameters(null, null, values[1]);
    if (values[0].equalsIgnoreCase("allow_duplicate_entries")) 
        allow_duplicate_entries = isTrue(values[1]);
}                         

我尝试使用value[0].equal("debug_mode")并获得相同的结果。 有人知道为什么吗?

11 个答案:

答案 0 :(得分:21)

确实很奇怪:)你可以将上面的代码更改为:

if ("debug_mode".equalsIgnoreCase("debug_mode")) 
    debug_mode = true;

确认它工作正常,然后仔细检查为什么values[0]不是“debug_mode”。

以下是我现在想到的一些要检查的内容:

  • 检查values[0].length() == "debug_mode".length()
  • 我非常怀疑,但无论如何,让我把它放在桌面上 - 你是否有机会使用Unicode?
  • 您可以打印每个字符并在该字符与“debug_mode”字符串的相应字符之间执行.equals()吗?
  • 如果这是一个更大的项目,你可以在一个简单的Java项目中做同样的事情并确认它在那里工作吗?

为了澄清,问题实际上是使用DataInputStream.readLine。来自javadoc(http://download.oracle.com/javase/1.6.0/docs/api/java/io/DataInputStream.html):

readLine()
      Deprecated. This method does not properly convert bytes to characters. ...

它实际上与一个微妙的方式有关 - 当你执行writeChar实际上你写了两个字节097,字母为{{1}的大端Unicode }}

这是一个显示行为的自包含代码段:

a

故事的道德 - 不要使用弃用的api ...而且,空白是无声的杀手:http://www.codinghorror.com/blog/2009/11/whitespace-the-silent-killer.html

答案 1 :(得分:7)

我使用equalsIgnoreCase刚刚遇到了同样的问题。

盯着屏幕几个小时后,调试我明白我的if语句有的代码;最后,

if ("stupid".equalsIgnoreCase.("STupid");
{
     //it always gets here 

}

希望这有助于将来。

答案 2 :(得分:3)

我和其他人在一起,这很疯狂,不应该发生。我同意打印出来可能有所帮助,但我会假设你已经尝试过了。

这可能是本地化问题吗?也就是说,当你在编辑器中键入debug_mode时(对于字符串),它是字符串“debug_mode”,但是当你在执行期间键入字符串时,终端被设置为使用不同的语言而你得到的是另一种语言(但是相同的人物?

要查找,请循环访问您输入的字符串并打印出每个字符的整数值,然后对您的字符串进行硬编码并查看它们是否相同。

String value = dis.readLine();
String values[] = value.trim().split("=");

System.out.println("Input:");

for (int i = 0; i < values[0].length(); i++) {
    System.out.print((int) values[0].charAt(i));
    System.out.print(' ');
}

System.out.println("Hardcoded:");

String debugMode = "debug_mode";

for (int i = 0; i < debugMode.length(); i++) {
    System.out.print((int) debugMode.charAt(i));
    System.out.print(' ');
}

现在要使其工作,您必须输入代码(或至少是debug_mode常量),因此它与您使用的字符集相同。

我愿意为这不是问题投入一大笔钱,但即使不是,它也应该证明是有益的,并向你展示不同的东西。

答案 3 :(得分:2)

尝试compareToIgnoreCase

if (values[0].compareToIgnoreCase("debug_mode") != 0) 
    debug_mode = true;

如果 不起作用,请尝试使用compareTo

如果 不起作用,请尝试:

String d = (String)values[0];
if (d.compareToIgnoreCase("debug_mode") != 0) 
        debug_mode = true;

如果那些不起作用,则会出现严重的 Java问题。无论是古老还是不喜欢你。

答案 4 :(得分:2)

虽然上面几乎没有很好的和正确的答案,但我仍然想提及我的个人经历,以便任何面临同样问题的人可以从这个答案中获得即时帮助。

我有两个不同的字符串说字符串A 字符串B 来自不同的来源,它们似乎与我相同但是我使用equals方法

对他们来说并不相同

即使使用 equalsIgnoreCase 也给了 false

我无能为力,因为当我打印那些字符串(A&amp; B)来检查它们看起来像什么时

String A is dsycuii343qzx899+ty=
String B is dsycuii343qzx899+ty=

所以,然后检查了两个字符串的长度,这给了我一些线索

String A length = 20
String B length = 21

这意味着我可能会遗漏一些东西,

所以我做的是

我用char 检查了每个String char,我知道了问题

似乎dsycuii343qzx899+ty=的字符串A实际上是dsycuii343qzx899+ty=\n

即最后有一个LF(新行字符),在日志检查时被注意到

希望它可以帮到某人。

答案 5 :(得分:0)

您可以在Android上使用SpannableString轻松地遇到此问题,就像TextView启用了自动链接一样,例如:

// Outputs "a string"
Log.d("test", "TextView text: " + textView.getText());

// Outputs "a string"
Log.d("test", "Text to match: " + "a string");

if( textView.getText().equals("a string") )
{
    // Won't get here
}

您可以通过快速测试来查看textView.getText()返回的字符串类型:

Log.d("test", "String class: " + textView.getText().getClass().getSimpleName());

如果你确实有SpannableString,你只需要调用toString()就可以满足if条件:

if( textView.getText().toString().equals("a string") )
{
    // We're here
}

答案 6 :(得分:0)

另一方面,在比较检索到的表的“状态”时,我有一个JSP页面有类似的问题:

try{



  // ID is a Primary Key (unique). STATUS column data type in DB: CHAR(20)
  rs = stmt.executeQuery("select STATUS from TEMP_TABLE WHERE ID='"+id+"'");

  while(rs.next()){

        status = (String) rs.getString("STATUS");

  }
   if ( status.equalsIgnoreCase("active") )
   {
          // Run some DB Queries
   } else {
           out.write("Page can't be accessed due to status : " + status);
   }
} catch(Exception e) { e.getMessage(); }
finally {
         //close all open objects
}

由于我不知道的原因,它总是点击else块,并显示消息“由于状态:活动状态,页面无法访问”,但状态为“活动”。我尝试在运行此查询之前和之后关闭每个查询后关闭rs和stmt对象,但这没有帮助。最后我将查询更改为

"select STATUS from TEMP_TABLE WHERE ID='"+id+"' where STATUS='ACTIVE'"

答案 7 :(得分:0)

我认为问题可能是虽然实际的String值相等,但它们的基础byte[]可能不是。

尝试使用此方法比较两个byte[]

private String printBytes(String str) {
    byte[] bytes = str.getBytes(ENCODING);
    String output = "byte[";
    for (int i = 0; i < bytes.length; i++) {
        output += Byte.toString(bytes[i]);
        if (i < bytes.length - 1) {
            output += ", ";
        }
    }
    output += "]";
    return output;
}

例如:

Charset ENCODING = Charset.forName("UTF-8");
Log.d(LOG_TAG, "string1: \"" + string1 + "\" - " + printBytes(string1));
Log.d(LOG_TAG, "string2: \"" + string2 + "\" - " + printBytes(string2));

这将实现视觉比较。对于较长的String,您可以通过同时迭代两个数组并比较值来以编程方式比较byte[]

答案 8 :(得分:0)

在我的情况下,我刚发现一个字符串在字符串之前有空格。 我的字符串就像“成功”和“成功”, 所以它正在返回<?php ini_set('display_errors', 1); $arr = array("abc-xyz","a pqr","rty'gjg","sdhf,sjh","dhd.jkyt"); $arr=preg_replace('/[\'\.,\s-]/', "_", $arr); print_r($arr); 。我用过:

false

因此解决了问题。

答案 9 :(得分:0)

可能是我的答案很晚,但是对某人有用。

只需在比较之前修剪()两个字符串

       eg: if(data1.trim().equalsIgnoreCase(data2.trim()))
            {
                //This gives proper result
            }

答案 10 :(得分:0)

可以是字节顺序标记:https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8

只需尝试str1.length()和str2.length(),如果不相同,请执行 str1.charAt(0)和y =如果您得到'\ uFEFF'65279 之类的东西,那不是您的问题