equal()和equalsIgnoreCase()对于相等的字符串返回false
我在mac上使用eclipse IDE(版本:3.4.2),我遇到了以下问题。
当使用equal()或equalsIgnoreCase()方法比较字符串时,即使字符串相等,我也会收到false。 例如,下面的代码将以下条件视为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")
并得到相同的结果。 有人知道为什么吗?
这确实很奇怪:)你可以将上面的代码更改为:
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
你实际上写了两个字节0
和97
,字母a
的大端Unicode。
这是一个显示行为的自包含代码段:
import java.io.*; import java.util.*; public class B { public static void main(String[] args) throws Exception { String os = "abc"; System.out.println("---- unicode, big-endian"); for(byte b: os.getBytes("UTF-16BE")) { System.out.println(b); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); for(char c: os.toCharArray()) { dos.writeChar(c); } byte[] ba = baos.toByteArray(); System.out.println("---- ba"); for(byte b: ba) { System.out.println(b); } ByteArrayInputStream bais = new ByteArrayInputStream(ba); DataInputStream dis = new DataInputStream(bais); System.out.println("---- dis"); String s = dis.readLine(); System.out.println(s); System.out.println("String length is " + s.length() + ", but you would expect " + os.length() + ", as that is what you see printed..."); } }
故事的道德 – 不要使用弃用的api …而且,空白是无声的杀手: http : //www.codinghorror.com/blog/2009/11/whitespace-the-silent-killer.html
我使用equalsIgnoreCase刚刚遇到了同样的问题。
几个小时的盯着屏幕,调试我明白的代码,我的if语句有一个; 在末尾,
即
if ("stupid".equalsIgnoreCase.("STupid"); { //it always gets here }
希望这有助于将来的某些人。
我和其他人在一起,这很疯狂,不应该发生。 我同意打印出来可能有所帮助,但我会假设你已经尝试过了。
是否可能是本地化问题? 也就是说,当你在编辑器中键入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常量),以便它具有与您使用的相同的字符集。
我愿意打赌这不是问题的一大笔钱,但即使它不是,它应该certificate是有益的,并告诉你什么是不同的。
尝试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问题。 无论是古老还是不喜欢你。
虽然上面几乎没有很好的正确答案,但我还是想提一下我的个人经历,这样任何遇到同样问题的人都可以从这个答案中获得即时帮助。
我有两个不同的字符串,表示字符串A和字符串B来自不同的来源, 它们看起来与我相同,但我使用equals方法对它们不相同
即使使用equalsIgnoreCase也给了我假
我很无能为力,因为当我打印那些字符串(A和B)来检查它们的样子时
String A is dsycuii343qzx899+ty= String B is dsycuii343qzx899+ty=
所以, 然后我检查了两个字符串的长度,这给了我线索
String A length = 20 String B length = 21
这意味着我可能会遗漏一些东西,
所以我做的是
我通过char检查了每个String char ,我知道了这个问题
字符串A看起来像dsycuii343qzx899+ty=
实际上是dsycuii343qzx899+ty=\n
即最后有一个LF
(新行字符),这是在Log检查时发现的
希望它可以帮助某人。
检查,仔细检查并重新检查。 显然你描述的情况是不可能的。
您可以使用SpannableString
轻松地在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 }
另一方面,在比较检索到的表的“状态”时,我有一个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'"
我认为问题可能是虽然实际的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
s,您可以通过同时迭代两个数组并比较值来以编程方式比较byte[]
。
在我的情况下,我刚刚发现一个字符串在字符串之前有空格。 我的字符串就像“SUCCESS”和“SUCCESS”,因此它返回false
。 我用了:
String st1=st.replaceAll("\\s","");
从而解决了问题。