String.equals против ==
Заголовок: Проблема с сравнением строк в Java
Я пытаюсь разделить строку на токены и сохранить их в массив строк. После этого я сравниваю переменную с первым элементом массива, но почему-то это не работает. Вот мой код:
public static void main(String...aArguments) throws IOException {
String usuario = "Jorman";
String password = "14988611";
String strDatos = "Jorman 14988611";
StringTokenizer tokens = new StringTokenizer(strDatos, " ");
int nDatos = tokens.countTokens();
String[] datos = new String[nDatos];
int i = 0;
while (tokens.hasMoreTokens()) {
String str = tokens.nextToken();
datos[i] = str;
i++;
}
//System.out.println (usuario);
if ((datos[0] == usuario)) {
System.out.println("WORKING");
}
}
Проблема в том, что сравнение строк с помощью оператора == не дает ожидаемого результата. Я ожидал, что при выполнении условия if ((datos[0] == usuario)) на консоли должно было появиться сообщение "WORKING". Однако этого не происходит. В чем может быть причина? Как правильно сравнивать строки в Java?
5 ответ(ов)
Вместо
datos[0] == usuario
используйте
datos[0].equals(usuario)
Оператор == сравнивает ссылки на объекты, в то время как метод .equals() сравнивает значения, что в данном случае является тем, что вам нужно.
Функция equals() является методом класса Object, который разработчик должен переопределить. Класс String переопределяет его для проверки, равны ли две строки, т.е. имеют ли они одинаковое содержимое, а не являются ли они одним и тем же объектом в памяти.
Оператор == проверяет, ссылаются ли обе переменные на один и тот же объект.
Рассмотрим следующие примеры программ:
String abc = "Awesome";
String xyz = abc;
if (abc == xyz)
System.out.println("Указывают на одну и ту же строку");
Здесь переменные abc и xyz ссылаются на одну и ту же строку "Awesome". Поэтому выражение (abc == xyz) возвращает true.
String abc = "Hello World";
String xyz = "Hello World";
if (abc == xyz)
System.out.println("Указывают на одну и ту же строку");
else
System.out.println("Указывают на разные строки");
if (abc.equals(xyz))
System.out.println("Содержимое обеих строк одинаково");
else
System.out.println("Содержимое строк различается");
В этом примере abc и xyz — это две разные строки с одинаковым содержимым "Hello World". Следовательно, выражение (abc == xyz) возвращает false, а (abc.equals(xyz)) — true.
Надеюсь, теперь вы понимаете разницу между == и <Object>.equals().
Спасибо.
Оператор == проверяет, указывают ли две ссылки на один и тот же объект или нет. Метод .equals() проверяет фактическое содержимое строк (значение).
Обратите внимание, что метод .equals() принадлежит классу Object (суперклассу всех классов). Вам необходимо переопределить его в соответствии с требованиями вашего класса, однако для строки он уже реализован и проверяет, имеют ли две строки одинаковое значение.
Пример 1)
String s1 = "Stack Overflow";
String s2 = "Stack Overflow";
s1 == s1; // true
s1.equals(s2); // true
Причина: Строковые литералы, созданные без null, хранятся в пуле строк в области перманентной памяти кучи. Поэтому как s1, так и s2 указывают на один и тот же объект в пуле.
Пример 2)
String s1 = new String("Stack Overflow");
String s2 = new String("Stack Overflow");
s1 == s2; // false
s1.equals(s2); // true
Причина: Если вы создаете объект String с помощью ключевого слова `new`, ему выделяется отдельное пространство в куче.
== проверяет равенство ссылок.
.equals() проверяет равенство значений.
Следовательно, если вы хотите проверить, имеют ли две строки одно и то же значение, вам следует использовать .equals() (за исключением некоторых случаев, когда вы можете гарантировать, что две строки с одинаковым значением будут представлены одним и тем же объектом, например, при интернировании строк).
== нужно использовать для проверки, являются ли две строки одним и тем же объектом Object.
// Эти две строки имеют одинаковое значение
new String("test").equals("test") ==> true
// ... но они не являются одним и тем же объектом
new String("test") == "test" ==> false
// ... и эти не равны
new String("test") == new String("test") ==> false
// ... а эти равны, потому что литералы интернируются компилятором и
// таким образом ссылаются на один и тот же объект
"test" == "test" ==> true
// Конкатенация строковых литералов происходит на этапе компиляции, что также приводит к одним и тем же объектам
"test" == "te" + "st" ==> true
// Но .substring() вызывается во время выполнения, создавая отдельные объекты
"test" == "!test".substring(1) ==> false
Важно отметить, что == значительно дешевле, чем .equals() (это лишь одна операция сравнения указателей вместо цикла), поэтому в ситуациях, когда это применимо (т.е. когда вы можете гарантировать, что имеете дело только с интернированными строками), это может обеспечить важное улучшение производительности. Однако такие ситуации достаточно редки.
Давайте проанализируем следующий код на Java, чтобы понять различия между идентичностью и равенством строк:
public static void testEquality(){
String str1 = "Hello world.";
String str2 = "Hello world.";
if (str1 == str2)
System.out.print("str1 == str2\n");
else
System.out.print("str1 != str2\n");
if(str1.equals(str2))
System.out.print("str1 equals to str2\n");
else
System.out.print("str1 doesn't equal to str2\n");
String str3 = new String("Hello world.");
String str4 = new String("Hello world.");
if (str3 == str4)
System.out.print("str3 == str4\n");
else
System.out.print("str3 != str4\n");
if(str3.equals(str4))
System.out.print("str3 equals to str4\n");
else
System.out.print("str3 doesn't equal to str4\n");
}
Когда выполняется первая строка кода String str1 = "Hello world.", создается строка "Hello world.", и переменная str1 ссылается на неё. При выполнении следующей строки кода другая строка "Hello world." не будет создана повторно из-за оптимизации. Переменная str2 также ссылается на уже существующую строку "Hello world.".
Оператор == проверяет идентичность двух объектов (ссылаются ли две переменные на один и тот же объект). Поскольку str1 и str2 ссылаются на одну и ту же строку в памяти, они идентичны друг другу. Метод equals проверяет равенство двух объектов (имеют ли два объекта одинаковое содержимое). Очевидно, что содержимое str1 и str2 одинаково.
Когда выполняется код String str3 = new String("Hello world."), создается новый экземпляр строки с содержимым "Hello world.", и он ссылается на переменную str3. Затем снова создается другой экземпляр строки с тем же содержимым "Hello world.", и он ссылается на str4. Поскольку str3 и str4 ссылаются на два разных экземпляра, они не идентичны, но содержимое у них одинаковое.
Таким образом, вывод будет содержать четыре строки:
str1 == str2
str1 equals to str2
str3 != str4
str3 equals to str4
Почему этот код с использованием случайных строк выводит "hello world"?
Преобразование 'ArrayList<String>' в 'String[]' в Java
Как сгенерировать случайную алфавитно-цифровую строку
Как преобразовать строку Java в byte[]?
Проверьте, что строка не равна null и не пуста