2009-12-02 2 views
0
String string1 = "Hi there"; 
String string2 = "Hi"; 
String string3 = "Hi"; 

System.out.println(string1.substring(0, string2.length()) == string2); //1 
System.out.println(string1.substring(0, string2.length()).equals(string2)); //2 
System.out.println(string1.substring(0, string2.length()).compareTo(string2)); //3 
System.out.println(string2 == string3); //4 
System.out.println(string2.substring(0) == string3); //5 
System.out.println(string2.substring(0) == string3.substring(0)); //6 

дает мне выход:Сравнение строк в Java

false 
true 
0 
true 
true 
true 

Я не очень понимаю, первая линия, почему это даст мне ложное?

Если добавить пробел в строку 2 и эту линию я получаю ложные, но если я не добавить никаких пробелов я правда:

System.out.println(string2.substring(0, string3.length()) == string3); 

Почему линия 1 дать мне ложные, но строка 6 быть правдой, но если добавить пробел строка2 это ложь ..

спасибо =)

+5

Как это не хватает? http://stackoverflow.com/search?q=Comparing+strings+in+java Разве вы не видели список со всеми ссылками ниже темы, когда вы ввели сообщение с вопросом? Вы потрудились следовать предложенным ссылкам? Почему нет? – BalusC

ответ

14

Несколько вещей, происходящих там.

Когда вы объявляете две строки равными «Привет», java оптимизирует ее, чтобы ссылаться на один и тот же строковый объект (поэтому ему не нужно хранить одну и ту же строку дважды).

"==" сравнивает ссылки. Когда в строке 1 вы используете подстроку, созданный строковый объект имеет другую ссылку, чем string2.

В строке 6 я предполагаю, что подстрока (0) имеет оптимизацию, где она знает, что она может просто вернуть исходную строку, поэтому эти ссылки равны.

+0

+1 для подробного объяснения – Yacoby

+0

Есть ли эти оптимизации ВСЕГДА были на Java? Кажется, я вспоминаю упражнение на Java 2, которое, возможно, не привело к разным результатам, но моя память немного туманна. – FrustratedWithFormsDesigner

+2

Возможно, может и нет. В любом случае это прекрасный пример того, что вы никогда не будете полагаться на такую ​​оптимизацию. Если вам нужно сравнить 'String', * always * используйте' equals() ', * never * use' == '! – Bombe

4

оператор == проверяет, если два объекта равны (они ссылается на тот же объект), не сравнивая значения containes в нем.

+0

Ну, тогда почему 4, 5 и 6 верны? –

+0

@Tor: Жан-Бармаш избил меня;) – FrustratedWithFormsDesigner

+0

Это неряшливая и запутанная терминология: оператор == не проверяет, равны ли два ОБЪЕКТА; он проверяет, ссылаются ли две переменные на один и тот же объект. Переменные не являются объектами - переменные являются ссылками на объекты. – Jesper

7

Если вы хотите сравнить строки, то вы должны использовать метод String.equals() (или String.equalsIgnoreCase()). Сравнение на == говорит вам, только если две ссылки указывают на один и тот же объект. И в вашем примере это то, что: string2 и string3 указывают на тот же экземпляр строки "Hi" (почему Java должно создавать две точно такие же строки, данные во время компиляции)

+1

+1. Стоит также отметить, что в целом существует очень мало гарантий того, какой экземпляр объекта вы вернетесь из метода - методы, как правило, могут делать гораздо приятнее, если они могут свободно использовать кэширование экземпляров, использовать динамические прокси и т. Д. важно не зависеть от равенства объектов и использовать 'equals()' в общем случае, сравнивая ссылки, только если вы действительно уверены, что вам это нужно. –

1

== сравнить ссылку - адрес строки не его значение. Для сравнения строк вы должны использовать equals. JVM будет обрабатывать новые объекты String, поэтому, если объект с тем же значением существует (строка2 vs string3), он может ссылаться на один и тот же.

1

Оператор == сравнивает 2 ссылки на одну и ту же строку для равенства.

Строка класс имеет два метода, которые следует использовать для сравнения двух строк на равенство:

String1.equals(String2); 

возвращает истину, если строка1 и String2 идентичны (включая регистр букв).

Если вы не заботитесь о том случае, то вы можете использовать:

String1.equalsIgnoreCase(String2); 

Это возвращает истину, если строка1 и String2 равны независимо от случая (очевидно).

2

Java предоставляет два основных механизма для тестирования .Оператор «==» может использоваться для проверки значений примитива для равенства, а также может быть , используемый для определения того, указывает ли два объекта на тот же объект . Для объектов Java метод equals (Object) возвращает true, если аргумент равен объекту , на котором вызывается метод, , где равенство определено семантикой класса объектов .

Так как строки являются объектами, метод в Equals (Object) возвращает истину, если две строки имеют то же содержание, т.е. одни и те же символы в том же порядке . Оператор == будет равен true, если две ссылки на String указывают на тот же базовый объект String. Следовательно две строка, представляющая одинакового содержания будет равна при испытании с помощью равенства методы (объекта), но будет только равен при испытании с оператором == , если они на самом деле тот же объектом .

Цитируется JavaTechniques: http://javatechniques.com/public/java/docs/basics/string-equality.html

1

линий 4, 5 и 6 представляют собой true из следующих строк в методе substring(int, int) из java.lang.String:

return ((beginIndex == 0) && (endIndex == count)) ? this : 
    new String(offset + beginIndex, endIndex - beginIndex, value); 

Поскольку подстроки вы запрос начинается с 0 и имеет длину полной строки, вы просто возвращаете ссылку на собственно строку, так что a.substring(0) == a.