2010-11-18 7 views
13

私はMacでEclipse IDE(バージョン:3.4.2)を使用しています。equal()とequalsIgnoreCase()は等しい文字列に対してfalseを返します

equal()またはequalsIgnoreCase()メソッドを使用して文字列を比較すると、文字列が等しい場合でもfalseが返されます。例えば、以下のコードは、以下の条件が偽考える場合でも、値[0] =次のループの一部である「debug_mode」

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

:私はvalue[0].equal("debug_mode")を使用しようとした

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

同じ結果を得ました。 誰かが理由を知っていますか?確かに非常に奇妙なことでしょう

+3

値の実際の値は何ですか?[0] – Bozho

+4

あなたは110%確信していますか?values [0]には値が "debug_mode"の文字列が含まれていますか?それをコンソールに印刷してください。 –

+0

この条件の前に値[0]を印刷できますか? –

答えて

20

:)あなたがこれに上記のコードを変更することができます:それはあなたのvalues[0]は「debug_mode」ではありません、なぜダブルチェック後、正常に動作して

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

確認。

ここでチェックするもののリストとして、今私の心に来るものだ:values[0].length() == "debug_mode".length()

  • は、私は非常に疑うこと

    • チェックは、しかし、私はとにかく、テーブルの上に置いてみましょう - あなたはどんなことですユニコードを使用するチャンス?
    • 各文字を印刷し、その文字と「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. ... 
    

    それは実際に微妙な方法でのUnicodeに関係している - あなたがwriteCharを行うときには、実際に手紙aのために2バイト097、ビッグエンディアン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

  • +1

    +1 *あなたの値[0]が「debug_mode」でない理由を確認してください* :-) –

    +0

    Hehe、thanks pst! –

    +1

    まあ、あなたはそれを非常に疑っていますが、実際問題はwriteUTF()の代わりにDataOutputStream.writeChar()を使ってファイルに書き込んだことです。それは問題を引き起こしました。 – MByD

    1

    チェック、ダブルチェック、再チェックを行います。明らかにあなたが描いている状況は不可能です。

    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の問題を持っています。どちらか古代かあなたが好きではありません。

    +0

    これらのメソッドが正しく動作しないJavaの古代または現代のバージョンはありません。それは、最初に自分自身をコンパイルすることはできませんでした。 – EJP

    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定数)を入力する必要があると思いますので、それはあなたが使用していると同じ文字セットを持っています。

    私はこれが問題ではないが、それが問題ではないが、それが有益であることを証明し、何が違うかを示すべきであるとしても、良いお金を賭けることを喜んでいるだろう。

    +0

    ありがとうございます。すでに解決済み:) – MByD

    0

    のTextViewがautolinkingは、例えば、を有効にしているとき、あなたは簡単のように、SpannableStringとAndroid上でこれにを実行することができます。

    // 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条件を満たすべき場合は、単にのためにそれにtoString()を呼び出す必要があり、

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

    あなたがSpannableString持って実際にした場合::()が実行して返します

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

    equalsIgnoreCaseを使用して、まったく同じ問題が発生しました。

    画面を見つめてから、コードをデバッグすると、私のif文には、最後に、

    すなわち

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

    が、これは将来的に誰かに役立ちます願っています。

    +0

    私はあなたがその愚かなエラーのために愚かだと思ったが、...私はmyselftに考えました:「それは常に人為的なエラーですので、私のコードをチェックさせてください。何が起こったの?それはあなたの同じエラーでした! :Pそして私はこれで約1時間を持っています –

    +0

    同様に、私はこの種のチェックを使ってメソッドから戻ることに問題がありました。 '' 'if(" stupid ".equalsIgnoreCase。(" STupid ")) ' '' if( "stupid" .equalsIgnoreCase。( "STupid"))return; '' ' リターンブロックをラップする必要がありました。 {return; } '' ' – providencemac

    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 
    } 
    

    を、それは常にメッセージ「ページで他のブロックを打つにはステータスが「アクティブ」であるにもかかわらず、「ステータス:アクティブ」のためアクセスできません。私はこのクエリを実行する前と実行した後、それぞれのクエリの後にrsとstmtオブジェクトを閉じようとしましたが、それは役に立たなかった。結局私は、問題は、実際のString値が等しいものの、その基礎となるbyte[]年代はないかもしれないことかもしれないと思う

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

    に私のクエリを変更しました。

    は2 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[]をプログラムで比較することができます。両方の配列を同時に繰り返して値を比較します。

    2

    I上記のいくつかの非常に良い、正しい答えがありますが、まだ同じ問題が直面している誰もがこの回答からインスタントの助けを得ることができるように私の個人的な経験に言及したいと思います。

    は、私は2つの異なる文字列が列切り抜いたソースから文字列Bは、は、彼らが私と同じように見えたと言っていたけど私は

    でも、equalsメソッドを使用しての彼らのために等しくないなっていましたequalsIgnoreCaseを使用して、私は(それらの文字列を印刷したときので、私は無知だった私に

    を与えました& B)は、彼らが

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

    ので、は、私はその後、私の

    String A length = 20 
    String B length = 21 
    

    はSOそれは私が何かが足りないかもしれない意味手がかりを与えた2つの文字列の長さをチェックしたどのように見えるかを確認します、私がしたので、何

    は、私は、各文字列cを確認

    ました文字とIによってHARはLF(改行文字)が最後であったすなわちログ

    を確認しながらdsycuii343qzx899+ty=のように思えた

    文字列が実際にdsycuii343qzx899+ty=\n

    気づいたされた問題を知るようになりました

    誰かを助けてくれることを願っています。

    0

    私の場合、文字列の前にスペースが1つあることがわかりました。 私の文字列は "  SUCCESS"と "SUCCESS"のように でしたので、falseを返していました。私は使用しました:

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

    このように問題が解決しました。

    関連する問題