Почему я могу использовать строки в качестве ключей в HashMap? - PullRequest
5 голосов
/ 24 февраля 2012

Если два String одинаковых на самом деле не идентичны, то почему я могу использовать строки в качестве ключей в HashMap без использования одного и того же объекта String?

String s1 = "Test";
String s2 = "Test";

System.out.println(s1 == s2); // should be false
System.out.println(s1.equals(s2)); // should be true

HashMap<String, String> map = new HashMap();
map.put(s1, "foo");
System.out.println(map.get(s2)); // should be "foo"--but why?

HashMap имеет какое-то особое поведение для String объектов?Если нет, то почему можно использовать две «разные» строки для ввода и получения значений из хеша?

Ответы [ 6 ]

14 голосов
/ 24 февраля 2012

HashMap сравнивает объекты, вызывая equals() и hashCode().
String переопределяет эти методы для сравнения по значению.

5 голосов
/ 24 февраля 2012

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

4 голосов
/ 24 февраля 2012

Если две одинаковые строки на самом деле не равны

Но они есть. Они равны в методе equals (), и это метод, указанный для проверки на равенство в интерфейсе Map.

System.out.println(s1 == s2); // should be false

Но это не так! Оба ссылаются на одну и ту же строку из-за постоянного пула компилятором.

2 голосов
/ 24 февраля 2012

Когда HashMap сравнивает ключ внутри, он использует метод equals(), а не ==.Таким образом, равенство объектов подходит для соответствия ключей, равенство ссылок не требуется, если equals() переопределено (как в случае java.lang.String.)

1 голос
/ 24 февраля 2012

System.out.println (s1 == s2); // должно быть ложным

Не должно. Компилятор Java может оптимизировать и указать две строки в одном месте.

Обновление

public class Test {

    public static void main(String... args) {
        String s1 = "abc";
        String s2 = "abc";

        System.out.println(s1 == s2);
    }

}

Выход

javac Test.java
java Test
> true
0 голосов
/ 24 февраля 2012

мы действительно должны сначала вернуться к основному.

фундаментальная информатика:

== сравнивает адрес памяти (ссылка)

.equals сравнивает значение, хранящееся в адресе памяти

Java базовый. есть только одна копия строкового объекта во всей jvm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...