2010-11-18 40 views
13

Tôi đang làm việc với nhật thực IDE (Phiên bản: 3.4.2) trên mac và tôi đã gặp vấn đề sau.bằng() và equalsIgnoreCase() trả về false cho các chuỗi bằng nhau

Khi so sánh giữa các chuỗi bằng các phương thức bằng() hoặc equalsIgnoreCase() tôi nhận được sai ngay cả khi chuỗi bằng nhau. Ví dụ, đoạn code dưới đây xem xét các điều kiện sau đây là sai sự thật, ngay cả khi giá trị [0] = "debug_mode"

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

mà là một phần của vòng lặp sau:

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

Tôi cố gắng để sử dụng value[0].equal("debug_mode") và có cùng kết quả. Có ai có ý kiến ​​gì không?

+3

giá trị thực tế của các giá trị [0] – Bozho

+4

Bạn có chắc chắn '%' '[0]' có chứa chuỗi có giá trị "debug_mode" không? In nó vào bàn điều khiển để chắc chắn. –

+0

bạn có thể in giá trị [0] trước điều kiện này không? –

Trả lời

20

Đó sẽ là rất lạ quả thật :) Bạn có thể thay đổi mã trên như sau:

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

xác nhận nó hoạt động tốt và sau đó kiểm tra tại sao values[0] của bạn không phải là "debug_mode" tăng gấp đôi.

Đây là những gì nói đến cái tâm của tôi ngay bây giờ như một danh sách những thứ cần kiểm tra:

  • Kiểm tra xem values[0].length() == "debug_mode".length()
  • Tôi rất nghi ngờ, nhưng hãy để tôi đặt nó trên bàn anyway - là bạn bởi bất kỳ cơ hội sử dụng Unicode?
  • Bạn có thể in từng ký tự và làm .equals() giữa ký tự đó và ký tự tương ứng của chuỗi "debug_mode" không?
  • Nếu đây là một dự án lớn hơn, bạn có thể làm tương tự trong một dự án Java đơn giản và xác nhận nó hoạt động ở đó không?

Để làm rõ, sự cố thực sự đang sử dụng DataInputStream.readLine. Từ 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. ... 

Nó thực sự đã làm với Unicode trong một cách tinh tế - khi bạn làm writeChar bạn thực sự viết hai byte 097, lớn-endian Unicode cho chữ a.

Dưới đây là một đoạn khép kín cho thấy các hành vi:

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..."); 
    } 
} 

đạo đức của câu chuyện - không sử dụng api NỮA ... Ngoài ra, khoảng trắng là kẻ giết người thầm lặng: http://www.codinghorror.com/blog/2009/11/whitespace-the-silent-killer.html

+1

+1 * kiểm tra lý do tại sao giá trị của bạn [0] không phải là "debug_mode" * :-) –

+0

Hehe, cảm ơn pst! –

+1

Vâng, bạn rất nghi ngờ nó, nhưng thực sự vấn đề là tôi đã viết vào tập tin bằng cách sử dụng DataOutputStream.writeChar() thay vì writeUTF(). và nó đã gây ra vấn đề. – MByD

1

Kiểm tra , kiểm tra lại và kiểm tra lại. Rõ ràng tình huống bạn mô tả là không thể.

2

Hãy thử compareToIgnoreCase:

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

Và nếu rằng không hoạt động, hãy thử compareTo để thay thế.

Và nếu rằng không hoạt động, hãy thử:

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

Và nếu những không làm việc, bạn có một vấn đề nghiêm trọng Java. Hoặc là cổ hoặc nó không thích bạn.

+0

Không có phiên bản Java cổ hay hiện đại, nơi các phương pháp này không hoạt động chính xác. Nó sẽ không thể tự biên dịch cho một sự khởi đầu. – EJP

3

Tôi với những người khác, điều này thật điên rồ và không nên xảy ra. Tôi đồng ý rằng in nó ra có thể giúp đỡ, nhưng tôi sẽ giả sử bạn đã thử điều đó.

Có thể đó là vấn đề địa phương hóa không? Tức là, khi bạn gõ vào debug_mode trong trình soạn thảo (cho chuỗi) thì đó là chuỗi "debug_mode", nhưng khi bạn nhập chuỗi trong khi thực thi, thiết bị đầu cuối được thiết lập để sử dụng một ngôn ngữ khác và bạn nhận được một sự khác biệt (nhưng giống hệt nhau) nhân vật?

Để tìm hiểu, lặp qua chuỗi bạn nhận được và in ra giá trị số nguyên của mỗi ký tự, sau đó thực hiện tương tự với chuỗi của bạn được mã hóa cứng và xem chúng có giống nhau hay không.

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(' '); 
} 

Bây giờ để làm việc này, bạn phải nhập mã (hoặc ít nhất là hằng số debug_mode) để nó có cùng ký tự như bạn đang sử dụng.

Tôi muốn sẵn sàng đặt cược một khoản tiền tốt không phải là vấn đề, nhưng ngay cả khi nó không phải là nó nên chứng minh hướng dẫn và cho bạn thấy những gì là khác nhau.

+0

Cảm ơn. đã được giải quyết :) – MByD

0

Bạn có thể dễ dàng chạy vào này trên Android với SpannableString, như khi một TextView có autolinking kích hoạt, ví dụ:

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

Bạn có thể làm một thử nghiệm nhanh để xem những gì loại chuỗi textView.getText() trả về bằng cách thực hiện:

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

Nếu thực sự bạn đã có một SpannableString, bạn chỉ cần gọi toString() trên đó nếu điều kiện để được thỏa mãn:

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

Tôi vừa gặp vấn đề tương tự, sử dụng equalsIgnoreCase.

Sau nhiều giờ nhìn chằm chằm vào màn hình, hãy gỡ lỗi mã mà tôi đã nhận ra rằng câu lệnh if của tôi có; ở phần cuối,

ví dụ:

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

} 

Hope this helps ai đó trong tương lai.

+0

Tôi nghĩ rằng bạn là một người ngu ngốc vì lỗi ngu ngốc đó, nhưng ... Tôi nghĩ rằng myselft: "Nó luôn luôn là lỗi của con người, vì vậy, hãy để tôi kiểm tra mã của tôi". Và những gì happend? Đó là lỗi của bạn !! : P Và tôi có gần một giờ với điều này –

+0

Tương tự như vậy, tôi đã có một vấn đề với cố gắng để trở về từ một phương pháp bằng cách sử dụng loại kiểm tra. '' 'if (" ngu ngốc ".equalsIgnoreCase. (" Ngu ngốc ")) trả về;' '' Tôi phải bọc khối trả về: '' 'if (" ngu ngốc ".equalsIgnoreCase. (" Ngu ngốc ")) { trở về; } '' ' – providencemac

0

Trên một lưu ý khác nhau, tôi đã có một trang JSP gặp vấn đề tương tự khi so sánh lấy ra "trạng thái" của một bảng:

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 
} 

Vì lý do lạ lẫm với tôi nó luôn luôn chạm khối khác với thông báo "Trang không thể truy cập do trạng thái: đang hoạt động ", mặc dù trạng thái là" đang hoạt động ". Tôi đã thử đóng rs và stmt đối tượng sau mỗi truy vấn trước và sau khi chạy Query này nhưng điều đó đã không giúp.Cuối cùng tôi đã thay đổi truy vấn của tôi để

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

Tôi nghĩ rằng vấn đề có thể rằng mặc dù String giá trị thực tế đều bình đẳng, cơ bản byte[] 'của họ s có thể không.

Hãy thử sử dụng phương pháp này để so sánh hai byte[] 's:

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

Ví dụ:

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

Điều này sẽ cho phép một so sánh trực quan. Đối với dài String s, bạn có thể so sánh các lập trình của byte[] bằng cách lặp qua cả hai mảng cùng một lúc và so sánh các giá trị.

2

Mặc dù có rất ít rất tốt và chính xác câu trả lời trên, chúng tôi vẫn muốn đề cập đến kinh nghiệm cá nhân của tôi vì vậy mà bất cứ ai phải đối mặt với cùng một vấn đề có thể nhận được sự giúp đỡ ngay lập tức từ câu trả lời này.

tôi có hai chuỗi khác nhau nói chuỗi Mộtchuỗi B đến từ các nguồn khác nhau, họ dường như giống hệt với tôi nhưng tôi đã nhận được không bình đẳng cho họ về việc sử dụng bằng phương pháp

thậm chí về việc sử dụng equalsIgnoreCase đã cho tôi false

Tôi đã thất bại vì khi tôi in chuỗi đó (A & B) để kiểm tra những gì họ trông giống như họ đã

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

vậy, tôi sau đó kiểm tra chiều dài của hai chuỗi đó đã cho tôi đầu mối

String A length = 20 
String B length = 21 

SO đó có nghĩa là tôi có thể thiếu một cái gì đó ,

vì vậy những gì tôi đã làm là

Tôi đã kiểm tra từng chuỗi c har bởi char và tôi đã nhận biết được vấn đề

Chuỗi Một mà dường như dsycuii343qzx899+ty= đã thực sự dsycuii343qzx899+ty=\n

tức là đã có một LF (mới nhân vật dòng) ở cuối, được chú ý trong khi Log kiểm tra

hy vọng nó có thể giúp ai đó.

0

Trong trường hợp của tôi, tôi vừa phát hiện ra một chuỗi có dấu cách trước chuỗi. Các chuỗi của tôi giống như "  THÀNH CÔNG" và "THÀNH CÔNG", vì vậy nó đã trở về false.Tôi đã sử dụng:

String st1=st.replaceAll("\\s",""); 

và do đó giải quyết được sự cố.

Các vấn đề liên quan