2014-08-30 5 views
-2

Я пытаюсь получить значение другого элемента в методах переопределения HashMap и метода hashcode. Почему rollId возвращается null, когда у меня есть тот же хэш-код для student1 и student3, а также эти 2 объекта равны? В идеале он должен вернуть мне 3. Ниже приведен фрагмент кода:Карта HashCode и Equals

Main Class

public static void main(String[] args) { 
    Map<Student, Integer> studentMap = new HashMap<Student, Integer>(); 
    Student student1 = new Student(); 
    student1.setRollId(1); 
    Student student2 = new Student(); 
    student2.setRollId(2); 
    studentMap.put(student1, 1); 
    studentMap.put(student2, 2); 
    for (Entry<Student, Integer> entry : studentMap.entrySet()) { 
     if (entry.getValue().equals(1)) { 
      student1.setRollId(3); 
     } 
    } 
    Student student3 = new Student(); 
    student3.setRollId(3); 
    System.out.println("Student1 HashCode " + student1.hashCode() 
      + " Student3 HashCode " + student3.hashCode()); 
    System.out.println("Object Equal === > " + student1.equals(student3)); 
    Integer rollId = studentMap.get(student3); 
    System.out.println("RollId is " + rollId); 

} 


Студент Класс

private Integer rollId; 

public Integer getRollId() { 
    return rollId; 
} 

public void setRollId(Integer rollId) { 
    this.rollId = rollId; 
} 

@Override 
public int hashCode() { 
    return rollId; 
} 

@Override 
public boolean equals(Object obj) { 
    Student student = (Student)obj; 
    if(this.rollId.equals(student.getRollId())) 
    { 
     return true; 
    } 
    return false; 

} 
+0

Вы должны размещать весь код, а не отрывками, так что хелперы может проверить ваш код. –

ответ

1

The HashMap в конечном итоге сохраняет пары ключ-значение в таблице, и она использует хэш-код данного ключа, чтобы вычислить индекс в таблице для его отображенным значением.

При изменении атрибута rollId, вы бы также изменить хэш-код ключа, который, в свою очередь, будет вызывать поиск во внутренней таблице для другого индекса, чем та карта первоначально используется для хранения значения ,

Например, таблица, возможно, была первоначально выделена с определенной емкостью 16, а две пары были сохранены по индексам 1 и 2 (с учетом rollId, установленного в объекте Student). После изменения хэш-ключа от 1 до 3 карта будет искать индекс 3, который не сохраняет никакого значения.

1

Вы не можете изменить хэш-ключ после он помещается на карту и ожидает, что карта будет продолжать работать правильно. Если вы хотите изменить ключ, вы должны удалить элемент, изменить ключ и снова вставить.

Из документации Java:

Примечания: большое внимание должно быть осуществлено, если изменяемые объекты используются в качестве ключей карты. Поведение карты не указывается, если значение объекта изменяется таким образом, который влияет на равные сравнения, пока объект является ключом на карте.

+0

Спасибо @Gene. Получил это ... Это изменчивый объект. Подтвердите ответ. –

+0

Этот ответ, в то время как истинное утверждение, не объясняет проблему в его коде .. studentMap не имеет добавленных записей .. поэтому student1 rollId никогда не изменяется.См. Ответ ниже – ErstwhileIII

+1

@ErstwhileIII Возможно, он изменил свой код после того, как посмотрел на него? Но это 'studentMap.put (student1, 1); studentMap.put (student2, 2); 'был там, когда я написал свой ответ. – Gene

0

Проблема с вашим кодом в том, что вы не добавили никаких значений в studentMap. Кроме того, я не понимаю, почему вы используете Integer для RollId и вычисляете int из этого для вашего хэш-кода. Если вам действительно нужен Integer для большего диапазона, есть вероятность, что 32-разрядный hashcode (как вы подсчитали) мой произведет дубликат для разных rollIds. Рассмотрим изменения в INT/

Попробуйте этот код:

StudentDriver Класс

package com.example.student; 

import java.util.HashMap; 
import java.util.Map; 
import java.util.Map.Entry; 

public class StudentDriver { 
    private static Student student1, student2, student3; 

    public static void main(String[] args) { 
     Map<Student, Integer> studentMap = new HashMap<Student, Integer>(); 

     student1 = new Student(); 
     student2 = new Student(); 

     student1.setRollId(1); 
     student2.setRollId(2); 

     studentMap.put(student1, student1.getRollId()); 
     studentMap.put(student2, student2.getRollId()); 

     for (Entry<Student, Integer> entry : studentMap.entrySet()) { 
      System.out.println("Entry information: " + entry.getValue()); 
      if (entry.getValue().equals(1)) { 

       student1.setRollId(3); 
      } 
     } 

     student3 = new Student(); 
     student3.setRollId(3); 

     System.out.println("Student1 Hashcode = " + student1.hashCode() 
          +", Student3 Hashcode = " + student3.hashCode()) ; 
     System.out.println("Object equal ==> " + student1.equals(student3)); 
     Integer rollId = student3.getRollId(); 
     System.out.println("RollId is " + rollId); 
    } 
} 

класс Student

package com.example.student; 

public class Student { 
    // Object fields 
    private Integer rollId; 

    public Integer getRollId() { 
     return rollId; 
    } 
    public Student setRollId(Integer rollId) { 
     this.rollId = rollId; 
     return this; 
    } 

    @Override 
    public int hashCode() { 
     return rollId.intValue(); 
    } 

    @Override 
    public boolean equals(Object other) { 
     return other instanceof Student && ((Student)other).getRollId() == rollId; 
    } 
} 
Смежные вопросы