5

String.equals против ==

18

Заголовок: Проблема с сравнением строк в 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 ответ(ов)

0

Вместо

datos[0] == usuario

используйте

datos[0].equals(usuario)

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

0

Функция 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().

Спасибо.

0

Оператор == проверяет, указывают ли две ссылки на один и тот же объект или нет. Метод .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`, ему выделяется отдельное пространство в куче.
0

== проверяет равенство ссылок.

.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() (это лишь одна операция сравнения указателей вместо цикла), поэтому в ситуациях, когда это применимо (т.е. когда вы можете гарантировать, что имеете дело только с интернированными строками), это может обеспечить важное улучшение производительности. Однако такие ситуации достаточно редки.

0

Давайте проанализируем следующий код на 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
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь