2013-12-18 29 views
5

Mam następujący kodDlaczego "==" czasami działa z String.trim?

public static void main(String... args) { 

    String s = "abc"; 
    System.out.println(s.hashCode()); 
    String s1 = " abc "; 
    System.out.println(s1.hashCode()); 
    String s2 = s.trim(); 
    System.out.println(s2.hashCode()); 
    String s3 = s1.trim(); 
    System.out.println(s3.hashCode()); 
    System.out.println(); 
    System.out.println(s == s1); 
    System.out.println(s == s2); 
    System.out.println(s == s3); 
} 

OP:

96354 
32539678 
96354 
96354 

false -- Correct 
true -- This means s and s2 are references to the same String object "abc" . 
false -- s3=s1.trim()... which means s3="abc" yet s==s3 fails.. If the above conditon were to be considered (s==s2 is true..) , this should also be true.. 

Dlaczego otrzymuję "false" kiedy sprawdzasz s == s3 ..

+3

@JigarJoshi - Wątpię, czy to duplikat. OP wie, kiedy użyć '==' i 'equals()'.To pytanie dotyczy konkretnego przypadku, w którym '==' zachowuje się inaczej w różnych sytuacjach. – SudoRahul

+1

@ R.J To pytanie nie powinno istnieć .. (lub OP musi tylko przejrzeć niektóre z innych duplikatów na ten temat) – user2864740

+3

@ user2864740 - Nie zgadzam się z tobą w tej sprawie. To dobre pytanie z bardzo konkretnymi wątpliwościami. Nie rozumiem, dlaczego to nie powinno istnieć. Głosowanie na ponowne otwarcie – SudoRahul

Odpowiedz

2
public String trim() { 
    int len = value.length; 
    int st = 0; 
    char[] val = value; /* avoid getfield opcode */ 

    while ((st < len) && (val[st] <= ' ')) { 
     st++; 
    } 
    while ((st < len) && (val[len - 1] <= ' ')) { 
     len--; 
    } 
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this; 
} 

Jak widać w Twoim przypadku (System.out.println(s == s2);) this jest zwracany który jest skierowany do tego samego odniesienia, dlatego można dostać prawdziwe.

+1

bardzo dziękuję .. – TheLostMind

5

becuase s1.trim() powróci nowy? instancja. Struny są niezmienne, więc za każdym razem gdy funkcja stosowana na smyczki następnie zostaną zwrócone nowa instancja i Używasz == który porównuje równość instancji

Edit: jak sugeruje Chris Hayes i RJ

trim jest sprytny i zwraca this, jeśli nie ma białych znaków do przycinania. W drugim przypadku masz "abc" białe spacje, więc w tym przypadku nie jest zwracana this, ale nowa instancja łańcucha.

kod źródłowy trim method

+0

@RJ - to jest moje pytanie ... – TheLostMind

+1

@RJ Ponieważ 'trim' jest sprytny i zwraca' this', jeśli nie ma białych znaków do przycinania. http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/String.java#String.trim%28%29 –

+0

@RJ Prawdopodobnie miałaby zaoszczędziło ci dużo żalu, aby było bardziej wyraźne w pierwszym komentarzu. :) –

2

Jeśli przyjrzeć String.trim zobaczysz, że to w końcu nazywa String.substring co z kolei zwraca new String(...) jeśli ciąg jest uzyskiwanie faktycznie przycięte. Dlatego nie działa ==.

1

Java 7 kod źródłowy java.lang.String.trim() (z zainstalowaną JDK) to:

public String trim() { 
    int len = value.length; 
    int st = 0; 
    char[] val = value; /* avoid getfield opcode */ 

    while ((st < len) && (val[st] <= ' ')) { 
     st++; 
    } 
    while ((st < len) && (val[len - 1] <= ' ')) { 
     len--; 
    } 
    return ((st > 0) || (len < value.length)) ? substring(st, len) : this; 
} 

Instrukcja return mówi, że jeśli nie ma zmian na łańcuch są przycięte, wówczas zostanie zwrócony, a więc y == S2:

String s = "abc"; 
String s2 = s.trim(); 
System.out.println(s == s2); // is true 

Gdy łańcuch ścięte musi zostać oczyszczony, java.lang.String.substring() jest wywoływana. Kod źródłowy dla podciągu() w Java 7 jest:

public String substring(int beginIndex, int endIndex) { 
    if (beginIndex < 0) { 
     throw new StringIndexOutOfBoundsException(beginIndex); 
    } 
    if (endIndex > value.length) { 
     throw new StringIndexOutOfBoundsException(endIndex); 
    } 
    int subLen = endIndex - beginIndex; 
    if (subLen < 0) { 
     throw new StringIndexOutOfBoundsException(subLen); 
    } 
    return ((beginIndex == 0) && (endIndex == value.length)) ? this 
      : new String(value, beginIndex, subLen); 
} 

Gdy String są przycięte musi być przycięte, a następnie podciąg() zwraca nowy ciąg:

new String(value, beginIndex, subLen) 

Dlatego s! = s3:

String s = "abc"; 
String s1 = " abc "; 
String s3 = s1.trim(); 
System.out.println(s == s3); // is false 

Kod źródłowy tej odpowiedzi jest dostępny na GitHub here.

Powiązane problemy