2017-11-23 25 views
1

이 질문은 꽤 아마추어 일지 모르지만, 같은 오브젝트 인스턴스를 키로 사용할 때 hashmap이 값을 저장하거나 검색하지 못하는 이유를 이해하는 데 어려움이있다. . 내 코드는 다음과 같습니다.해시 코드를 오버라이드 한 후에도 같은 값의 오브젝트를 모두 오버라이드 한 후에도 HashMap 값을 모두 가져 오지 않는다.

public class Candidate { 

    private String id; 
    private String name; 

    public Candidate (String id, String name){ 
     this.id = id; 
     this.name = name; 
    } 

    public static void main(String args[]){ 
     Candidate cad = new Candidate("101","hari"); 

     HashMap<Candidate,String> mp = new HashMap<Candidate,String>(); 
     mp.put(cad, "sachin"); 
     mp.put(cad, "shewag"); 

     for(Candidate cand : mp.keySet()){ 
      System.out.println(mp.get(cand).toString()); 
     } 
    } 

해시 코드를 오버라이드하고 다음과 같습니다.

@Override 
    public boolean equals(Object obj){ 
     Candidate cad =(Candidate)obj; 
     if(!(obj instanceof Candidate)){ 
      return false; 
     } 
     if(cad.id.equals(this.id) && cad.name.equals(this.name)){ 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public int hashCode(){ 
     return Objects.hash(id, name); 
    } 

해시 맵의 크기를 가져 오려고하면 하나만 반환됩니다. 즉, 해시 맵에 처음 삽입 될 때 두 번째 삽입이 무시됩니다.

두 개의 값을 삽입하기 위해 동일한 후보 인스턴스를 사용하고 있기 때문에 그것이 사용 되었습니까? hashmap이 키와 값 쌍을 모두 삽입하도록 할 수 있습니까?

+3

이 캐스트'후보 CAD = (후보) obj가, '이전에 검사에 'obj instanceof Candidate'는 기다리고있는 ClassCastException처럼 보입니다. –

답변

3

지도 뒤에있는 전체 개념은 1) 키가 고유 - 특정 키에 대해 하나의 키/값 쌍만 보유하고 2) 조회가 상대적으로 "저렴한"것입니다.

HashMap 내에 하나의 객체 만 있습니다. 다른 키, 값 쌍을지도에 추가 할 때 키가지도의 이전 항목과 같으면 이전 항목은 으로 바뀌고 새 항목은으로 바뀝니다. 두 개 이상의 항목을 추가하려면 다른 키를 사용하거나 List<...> 개체를 값으로 사용하는지도를 만드십시오. 예를 들어,이 상황에서

HashMap<Candidate, List<String>> 

, 먼저지도는 후보 항목을 보유하고 있는지 확인 것이고, 그렇다면, 그 목록에 새 문자열을 추가합니다. 그렇지 않다면 새로운 ArrayList<String> 값을 가진 새로운 후보자를 추가하십시오. 보통 난 그냥이 목적을 위해 방법을 사용, 뭔가 같은 :

public static void put(Candidate cand, String text) { 
    if (newMap.containsKey(cand)) { 
     newMap.get(cand).add(text); 
    } else { 
     List<String> list = new ArrayList<>(); 
     list.add(text); 
     newMap.put(cand, list); 
    } 
} 

그리고 네, 코멘트에 d.j.brown 상태로, 클래스 캐스트 예외를 피하기 위해 당신의 equals 메소드를 해결. 그래서 같은

뭔가 :

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Objects; 

public class MyCandidateTest { 
    private static Map<Candidate, List<String>> newMap = new HashMap<>(); 

    public static void main(String args[]) { 
     Candidate cad = new Candidate("101", "hari"); 

     put(cad, "Foo"); 
     put(cad, "Bar"); 

     for (Candidate cand : newMap.keySet()) { 
      System.out.println(newMap.get(cand).toString()); 
     } 
    } 

    public static void put(Candidate cand, String text) { 
     if (newMap.containsKey(cand)) { 
      newMap.get(cand).add(text); 
     } else { 
      List<String> list = new ArrayList<>(); 
      list.add(text); 
      newMap.put(cand, list); 
     } 
    } 

} 

public class Candidate { 

    private String id; 
    private String name; 

    public Candidate(String id, String name) { 
     this.id = id; 
     this.name = name; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     // Candidate cad =(Candidate)obj; // !! no 
     if (!(obj instanceof Candidate)) { 
      return false; 
     } 
     Candidate cad = (Candidate) obj; // !! yes 
     if (cad.id.equals(this.id) && cad.name.equals(this.name)) { 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public int hashCode() { 
     return Objects.hash(id, name); 
    } 
} 
+0

내지도에 String 목록을 추가하거나 같은 값을 가진 다른 인스턴스를 만드는 중입니다. 나는이 해결책이 효과가 있다는 것을 안다. 하지만 hashmap에 동일한 키를 가진 2 개의 값을 저장하는 방법이 있습니까? 해시의 관점에서 HashCode와 equals의 목적은 무엇입니까? – user1734698

+0

@ user1734698 ** no **, 처음에는'HashMap'의 포인트입니다 – Eugene

+0

@Eugene : 알았어요! – user1734698

2

당신이 java-8 BTW, 간단한 예와 함께 원하는 것을 할 수있는 간단한 방법이있다 :

보조 노트에
HashMap<String, List<String>> mp = new HashMap<>(); 

    List<String> list = Arrays.asList("aa", "aa", "bb", "bb"); 

    for (String s : list) { 
     mp.computeIfAbsent(s, k -> new ArrayList<>()).add("c"); 
    } 

    System.out.println(mp); // {bb=[c, c], aa=[c, c]}