2013-09-01 3 views
1

Это класс, который мы будем использовать для добавления в hasmap. Он преодолел и методы equals(), и hashcode().Работа hashcode() и equals() в java?

class Dog 
    { 
     public String name; 
     public Dog(String n) 
     { 
      name=n; 
     } 
     @Override 
     public int hashCode() { 
      System.out.println("in hashcode"); 
      return name.length(); 
     } 
     @Override 
     public boolean equals(Object obj) { 
      System.out.println("in equals"); 
      if (this == obj) 
       return true; 
      if (obj == null) 
       return false; 
      if (getClass() != obj.getClass()) 
       return false; 
      Dog other = (Dog) obj; 
      if (name == null) { 
       if (other.name != null) 
        return false; 
      } else if (!name.equals(other.name)) 
       return false; 
      return true; 
     } 


    } 

Этот код в главном

Map<Object,Object> m=new HashMap<Object,Object>(); 
     Dog d1=new Dog("clover"); 
     m.put(d1,"Dog Key"); 
     System.out.println(m.get(d1)); 

производит

in hashcode 
in hashcode 
Dog Key 

, но следующий код

Map<Object,Object> m=new HashMap<Object,Object>(); 
     Dog d1=new Dog("clover"); 
     m.put(d1,"Dog Key"); 
     System.out.println(m.get(new Dog("clover"))); 

производит

in hashcode 
in hashcode 
in equals 
Dog Key 

Как вы можете видеть, есть вызов метода equals() во втором выходе. Почему это так?
Мой второй вопрос
Если изменить имя атрибута ключа Map м = новый HashMap();

Dog d1=new Dog("clover"); 
     m.put(d1,"Dog Key"); 

     d1.name="arthur"; 
     System.out.println(m.get(new Dog("clover"))); 

о/р

in hashcode 
in hashcode 
in equals 
null 

, даже если я изменил значение ключа, но я пытаюсь получить значение, давая одинаковый ключ. Тогда почему он возвращает нуль?

ответ

3

Для первого вопроса: HashMap необходимо позвонить по телефону equals(), чтобы подтвердить, что два объекта Dog, оба из которых имеют одинаковый хеш-код, на самом деле равны. Не нужно звонить equals() в первый раз, потому что он использует ==, чтобы проверить специальный случай использования того же самого объекта, который был указан ранее.

Для второго вопроса: вы изменили элемент данных, который меняет расчет хэш-кода и результат equals(). Это особенно противоречит правилам, и в результате карта повреждена; в этот момент все может случиться. Никогда не используйте объекты с изменяемыми данными для ключей в HashMap!

+0

Этот ответ уже завершен. Я хотел бы добавить некоторую общую информацию о том, как работает hashmap http://javarevisited.blogspot.ch/2011/02/how-hashmap-works-in-java.html – blackbird014

1

Это происходит потому, что после того, как вы кладете d1=new Dog("clover") в HashMap, вы измените свое название d1.name="arthur"; так Собака с именем arthur больше не равна new Dog("clover").

Так сначала сначала проверяется ключевой хэш-код, и он соответствует "clover".length равен "arthur".length, и это позволяет идентифицировать ведро, в котором находится ваш объект. После этого выполняется проверка equals(), чтобы получить нужный объект из ведра, и это не удается, так как ваш ключ не равен предоставленному.

На самом деле, нецелесообразно использовать изменяемые поля для вычисления хэш-кода.

1

Давайте рассмотрим, как работает HashMap.

  1. Многие объекты могут иметь одинаковый хэш-код.Когда вы помещаете объект в карту, он создает таблицу на основе результата метода hashCode. HashMap хранит объекты с одним и тем же хэш-кодом в списке, и каждый такой список присоединяется к таблице с ячейкой, связанной с конкретным хэш-кодом.
  2. Когда вы получаете объект с карты, он оценивает хэш-код переданного ключевого объекта, а затем получает список объектов, связанных с данным хэш-кодом. Затем он находит объект в списке, используя метод equals.

Использование правильного алгоритма хэш-кодирования и настроек емкости для HashMap позволяет достичь O (1) исполнения на месте и получить в целом.

Теперь давайте рассмотрим ваши вопросы:

  1. Вы идете поместить затем получить от HashMap. Вы видите оператор «в равных», потому что у вас есть другой объект для ключа. Существует немного оптимизации, когда ключи одинаковы, в этом случае HasMap не вызывает метод equals. В первом случае d1 == d1, но d1! = New Dog («clover») для второго.
  2. Ваши объекты имеют одинаковый хэш-код, но они больше не равны. И ключи отличаются

Но если вы измените свой код в этом:

Dog d1=new Dog("clover"); 
    m.put(d1,"Dog Key"); 

    d1.name="arthur"; 
    System.out.println(m.get(d1)); 

Это должно дать вам atrhur в конце концов.

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