Почему это равенство для проверки другого объекта String.java ?

#java #string

#java #строка

Вопрос:

В String.java , этот код находится в начале .equals() метода:

 public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    // ... check if instance of String, etc.
}
  

Является ли эта проверка чисто из соображений производительности (т. Е. Не включая ее, Будет проверять символы this против самого себя)?

Комментарии:

1. == проверьте hash code сначала, прежде чем сравнивать символы. == проверяет ссылки в памяти, если они совпадают, тогда нет смысла сравнивать один и тот же объект с самим собой.

2. Является ли эта проверка чисто из соображений производительности — да. Эта оптимизация, вероятно, особенно полезна, поскольку многие строки в Java интернированы , но поскольку интернированы не все строки, она также может вернуться к глубокому (char-by-char) сравнению равенства.

3. == не является проверкой для hashCode() , хотя это не первый раз, когда я вижу эту идею, выраженную в SO. public static class Thingy { Строковое значение; public Thingy(строковое значение) { this.value = value; } @Override public int hashCode() {return 1;} } public static void main(строка[] аргументы) { Thingy A = новая вещь («A»); Thingy B = новая вещь («B»); System.out.println(«A.hashCode() == B.hashCode() : » (A.hashCode()== B.hashCode()) ); System.out.println(«A == B : » (A == B)); }

4. @user2321368 — Это хороший момент — но ФУ!!! Может быть, вы можете ссылаться на суть или что-то в этом роде вместо того, чтобы пытаться встроить весь этот код в свой комментарий.

5. Наличие одного и того же хэш-кода не означает равенства, поскольку 2 одинаковых объекта ДОЛЖНЫ иметь один и тот же хэш-код, но 2 разных объекта НЕ должны иметь другой хэш-код. (отсюда и коллизии хэшей, если вы не выполняете достаточно хорошую хэш-функцию)

Ответ №1:

Да, это так. Поскольку они являются ссылками на один и тот же объект, несомненно, что они равны.

 String a = "foobar";
a.equals(a) // true
  

Ответ №2:

В Java a String — это представление массива символов. Когда вы вызываете .equals() этот объект, он проверяет каждый символ в массиве, чтобы увидеть, совпадают ли они при циклическом просмотре.

Сравнение в начале .equals() проверяет, сравниваете ли вы его с тем же объектом, таким образом, если да, то время меняется с O (n) (где n — размер строки в символах) на O (1).

Комментарии:

1. Обратите внимание, что та же логика также применима к instanceof проверке и сравнению длины. Обе эти проверки являются дешевыми, которые могут дать O (1) вместо того, чтобы сравнивать каждый символ.

Ответ №3:

Особенность строк в том, что при их создании они хранятся в куче для повторного использования.. итак, когда вы делаете это

 String a = "abc";
String b = "abc"; //implicitly referencing same string object as a
a.equals(b); //true because of reference
a == b; //true because of reference
  

На самом деле они неявно ссылаются на один и тот же объект в куче.

если вы не сделаете это:

 String a = "abc";
String b = new String("abc"); //explicitly creating a new string object
a.equals(b); //true because of value
a == b; //false because of reference