2012-02-23 2 views
5

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

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

Обратите внимание, что 's1 == s2' будет' истинным' из-за интернирования строк. –

+0

Тогда почему стандартная практика использует '.equals()' для сравнения 'String'? –

+1

@Ted Hopp s1 == s2 будет истинным из-за * постоянного объединения *. – EJP

ответ

14

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

4

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

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

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

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

2

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

5

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

1

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

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

Update

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

Неправильно, неправильно, неправильно. Вы можете легко доказать это простым кодом. – duffymo

+3

Нет, это не так. Это называется «интернированием». –

+2

«Может оптимизировать». Я думаю, вы имеете в виду «нужно оптимизировать», предполагая, что компилятор Java соответствует спецификации. http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.10.5 – yshavit

-2

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

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

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

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

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

+3

Почти каждая строка в вашем ответе тонко или нагло ошибочна – SLaks

+0

Это не «основы для компьютерных наук». Это * Основы Java *. Ссылка на Java не обязательно является адресом памяти. Может быть несколько копий строки, если вы используете конструкцию 'new String (...)'. – EJP

Смежные вопросы