2012-09-30 3 views
2

중복 키가 삽입 될 때 Java HashMap과 관련하여 매우 기본적인 의심이있었습니다.중복 키가 삽입 될 때 Java HashMap

제 의도는 4 개의 Emp 객체를 만드는 것입니다. 2 객체 (e1과 e2)는 동일한 hashCode를가집니다. 따라서 e1 (e2 이후에 삽입 됨)을 삽입하면 해시 맵은 이미 동일한 해시 값을 가진 객체 (객체 e2)가 있음을 인식합니다. 그런 다음 슬롯에있는 모든 객체의 키를 동일한 해시 값과 비교합니다. 아래의 Emp 클래스의 equals 메소드를 호출하여 일치하는 키를 가진 객체를 찾으면 이전 값을 새 값으로 바꿉니다.

아래의 테스트 코드에서 참조하시기 바랍니다 :

import java.util.Map; 
import java.util.HashMap; 
import java.util.Set; 

class Emp { 
     String name; 
     int age; 

     public Emp(String name, int age) { 
       this.name = name; 
       this.age = age; 
     } 

     public boolean equals(Object s) { 
       if(s instanceof Emp) { 
         Emp s1 = (Emp) s; 
         return ((s1.name.compareToIgnoreCase(this.name) == 0)); 
       } 
       return false; 
     } 

     public int hashCode() { 
       //return (this.name.hashCode() + this.age); 
       return this.name.hashCode(); 
     } 
} 

public class HashTest { 
     public static void main(String[] args) { 
       Emp e1 = new Emp("Terry", 26); 
       Emp e2 = new Emp("Terry" , 60); 
       Emp e3 = new Emp("John", 21); 
       Emp e4 = new Emp("Test", 60); 

       Map<Emp,Emp> emp = new HashMap<Emp, Emp>(); 
       emp.put(e2,e2); 
       Emp v2 = emp.put(e1,e1); 
       emp.put(e3,e3); 
       emp.put(e4,e4); 

       System.out.println("Replaced Record Name: " + v2.name + " , age: " + v2.age); 
       for(Emp e: emp.keySet()) 
         System.out.println("Name: " + e.name + " , age: " + e.age); 
     } 
} 

내가 기대 한 출력 : 대체 기록 이름 : 테리, 나이 : 60 이름 : 테스트, 연령 : 60 이름 : 테리, 나이 : 26 이름 : 존, 연령 : 21

내가 가진 출력 : 대체 기록 이름 : 테리, 나이 : 60 이름 : 테스트, 연령 : 60 이름 : 테리, 나이 : 60 이름 : 존, 연령 : 21

내가 (테리, 60)을 기대했다가 (테리, 26) 객체로 대체 할 . 이것은 내가 일어나는 것으로 보인다 대체 된 레코드 이름 : 테리, 나이 : 60 출력. 그러나,이지도는 레코드 을 포함하고 있습니다. 이름 : Terry, 연령 : 대신 60 이름 : Terry, 연령 : 26.

편집 : 제안에 감사드립니다. 나는 아주 부주의 한 실수를 저질렀다. 키와 관련된 값을 인쇄하는 대신 키만 인쇄했습니다.

for(Emp e: emp.keySet()) 
    { 
     Emp empVal = emp.get(e); 
     System.out.println("Name: " + empVal.name + " , age: " + empVal.age); 
    } 

답변

2

당신의 출력은 키가 아닌 값을 인쇄한다 : 모두가 지적했듯이

는 솔루션이다. 코드에서 키는 변경되지 않지만 값은 변경됩니다. 당신이 당신의 출력 루프 변경하는 경우 예를 들어

:

for (Emp emp : emp.values()) { 
    System.out.println("Name: " + e.name + " , age: " + e.age); 
} 

을 난 당신이 기대했던 대답을 볼 수 있습니다 생각한다.

그러나 일반적으로 나는 여기서하고있는 일을하지 말라고 조언합니다. 모든 종류의 코드는 a.equals(b)이면 ab에 아무런 의미있는 차이가 없으며 Emp 클래스의 equals 구현이 해당 계약에 부합하지 않을 것으로 예상합니다. 예를 들어, HashMap 대신 HashSet을 사용하면 훨씬 더 독특한 동작을 얻을 수 있으며 수정할 방법이 없습니다.

EmphashCodeequals 방법이 제대로 이름과 나이를 존중해야 할 수 있습니다이를 구현 및지도가 키가 직원의 이름과 값이 Emp 기록하는 Map<String, Emp>이 될 수 있도록 더 좋은 방법.

+0

jacobm 좋은 캐치를 주셔서 감사합니다. 나는 이렇게 오래 머물렀다. 부주의 한 실수는 싫어. ( – FunBoy

0

코드를 약간 수정했습니다 (아래 참조). 새로운 값이 맵에 배치됩니다 만, 키가 동일하므로, 2 번째의 put는 기존의 키를 재사용합니다.

public static void main(String[] args) { 
    Emp e1 = new Emp("Terry", 26); 
    Emp e2 = new Emp("Terry", 60); 

    Map<Emp, Emp> emp = new HashMap<Emp, Emp>(); 
    emp.put(e2, e2); 
    Emp v2 = emp.put(e1, e1); 

    System.out.println("Replaced Record Name: " + v2.name + " , age: " + v2.age); 
    for (Emp e : emp.keySet()) { 
     System.out.println("[key] Name: " + e.name + " , age: " + e.age); 
     System.out.println("[value] Name: " + emp.get(e).name + " , age: " + emp.get(e).age); 
    } 
} 

는 출력 : 당신이 실제로 키를 인쇄하는 아래의 문 ..에서

[key] Name: Terry , age: 60 
[value] Name: Terry , age: 26 
0

keySet()를 호출하여, 당신은 map에서 키의 Set 얻을, 당신은 그 열쇠 반복하고 인쇄 .. 당신은지도에서 해당 키의 값을 가져오고 그들을 인쇄 .. 그래서, 아래의 문으로 변경해야합니다 -

System.out.println("Name: " + e.name + " , age: " + e.age); 

과를 : -

System.out.println("Name: " + emp.get(e).name + " , age: " + emp.get(e).age);