2017-02-09 22 views
0
package com.sample; 

import java.util.HashMap; 

class Student{ 
    int id; 

    @Override 
    public int hashCode() { 
     return -1; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return false; // returning false 
    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Student s1=new Student(); 
     s1.id=123; 
     Student s2=new Student(); 
     s2.id=456; 

     HashMap<Student,String> s=new HashMap<Student,String>(); 


     s.put(s1, "One"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     s.put(s2, "Two"); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 
     s.put(s1, "Three"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 

     System.out.println("after insert"); 

     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 


    } 

} 



OUTPUT 

< s1 value > One < s1 hashcode > 79430 
< s2 value > Two < s2 hashcode > 84524 
< s1 value > Three < s1 hashcode > 80786814 
after insert 
< s1 value > Three < s1 hashcode > 80786814 //printing three for s1 
< s2 value > Two < s2 hashcode > 84524 //printing two for s2 

// Теперь, если мы изменим возвращаемый тип метода equals на true, выходные изменения и оба возвращают три в качестве вывода. Я не могу понять, почему вывод изменяется, если мы меняем возвращаемый тип метода equals. Пожалуйста, объясните в контексте метода bucket (HashMap) и equals.Почему выход изменяется, если мы изменим возвращаемое значение метода equals?

class Student{ 
    int id; 

    @Override 
    public int hashCode() { 
     return -1; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return true; //returning true 
    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Student s1=new Student(); 
     s1.id=123; 
     Student s2=new Student(); 
     s2.id=456; 

     HashMap<Student,String> s=new HashMap<Student,String>(); 


     s.put(s1, "One"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     s.put(s2, "Two"); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 
     s.put(s1, "Three"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 

     System.out.println("after insert"); 

     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 


    } 

} 


OUTPUT- 

< s1 value > One < s1 hashcode > 79430 
< s2 value > Two < s2 hashcode > 84524 
< s1 value > Three < s1 hashcode > 80786814 
after insert 
< s1 value > Three < s1 hashcode > 80786814 //printing three for s1 
< s2 value > Three < s2 hashcode > 80786814 //printing three for s2 
+0

См. [Почему для карты используется метод equals для проверки ключей] (http://stackoverflow.com/questions/31860486/does-a-map-using-equals-method-for-key-checking-exists) –

ответ

3

В своем первом фрагменте, ваш метод equals всегда возвращает false, что означает, что HashMap рассматривает все Student экземпляров должны быть уникальными. Поэтому s.get(s1) и s.get(s2) возвращают разные значения.

В вашем втором фрагменте, ваш метод equals всегда возвращает true и ваш hashCode всегда возвращает -1, что означает, что HashMap рассматривает все экземпляры Student быть одинаковыми. Поэтому s.get(s1) и s.get(s2) оба возвращают одинаковое значение (каждый вызов put переопределяет предыдущее значение). Значение «Три», так как это последнее значение, которое вы положили на карту (путем вызова s.put(s1, "Three");).

приписка, печать s.get(s1).hashCode() кажется бессмысленным, так как это hashCode ключа (s1.hashCode()), который определяет ведро, в котором запись будет храниться в HashMap, а не hashCode значения.

Кстати, я изначально был удивлен, что ваш первый фрагмент не возвращается во всех вызовах s.get()null, поскольку equals всегда возвращает false, поэтому HashMap не должен быть в состоянии определить местонахождение key который equal для данного ключа , Однако, проверяя исходный код HashMap, я обнаружил, что ключи сначала сравниваются с == до того, как equals вызывается, поэтому HashMap может найти ваши ключи.

+0

Привет, Eran, У меня есть сомнение в первом фрагменте, когда метод equals возвращает false. Во-первых, когда мы делаем, s.put (s1, «One»), это сохранит значение в HashMap, но опять же, когда мы делаем s.put (s1, «Three»), почему это заменяет значение и не исключение? –

+0

Согласно моему пониманию, когда мы используем s.put (s1, «Three»), он будет выполнять хэширование по ключу и получать индекс ведра и сохраняет значение в этом индексе. Теперь, когда мы делаем s.put (s1, «Three»), он будет выполнять hasing на ключе и получить индекс bucket, он будет сравнивать ключ с входом в этом индексе, тогда он всегда будет возвращать false как equals метод переопределяется, чтобы возвращать false каждый раз. Таким образом, у него должна быть еще одна запись, но с еще одной записью с тем же ключом будут нарушены свойства hashmap, поэтому она должна возвращать ошибку. –

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

  • Нет связанных вопросов^_^