💻 Study/Java

[Java] 컬렉션 프레임워크9_HashMap

와자! 2023. 3. 11. 20:54
728x90
728x90
이 게시글은 남궁성의 정석코딩 - 자바의 정석 기초편(2020최신)을 보고 공부한 내용을 정리한 게시글입니다.
틀린 내용이 있을 수 있습니다.

 

 

 

 

HashMap

- Map 인터페이스를 구현한 대표적인 컬렉션 클래스이다. 

Map 인터페이스
대표적으로 Hashtable, HashMap, TreeMap이 있다.

Hashtable : 옛날버전으로 동기화되어 있다.
HashMap : 최신버전으로 동기화되어 있지 않다. 카와 값을 데이터로 저장한다. 데이터 검색이 빠르다.
TreeMap : 키와 값을 데이터로 저장한다는 것을 빼면 TreeSet과 같은 속성을 가지고 있다. 범위 검색과 정렬에 유리하지만, HashMap보다 데이터 추가, 삭제에 시간이 더 걸린다.

 

- 데이터를 키(key)값(value)의 쌍으로 저장한다.

- 순서 X, 중복(키 X, 값 O)

- 순서를 유지하고 싶다면 LinkedHashMap 클래스를 사용하면 된다.


키(key)
: 컬렉션 내에서 동일한 키는 있을 수 없다.
값(value) : 키와 달리 중복되는 값을 허용한다.
ex) 사이트 가입 시 이미 있는 아이디는 만들 수 없고, 패스워드는 상관없다.

키와 값의 쌍을 entry라고 부른다.

 

- 해싱(hashing) 기법으로 데이터를 저장한다. 해싱 기법으로 인해 데이터가 많아도 빠르게 검색할 수 있다.

 

 

 

해싱기법(hashing)

해시함수로 해시테이블에 데이터를 저장하고 검색하는 것을 말한다.

왼쪽 - 해시함수, 오른쪽 - 해시테이블

해시함수 : key 값을 넣으면 배열의 저장위치(해시코드)를 알려주는 함수이다.

해시코드 : 배열의 인덱스이다. key 값에 대해 항상 같은 해시코드를 반환한다. 서로 다른 key값에 대해 같은 해시코드를 반환할 수도 있다.

해시테이블 : 배열의 우수한 접근성과 변경에 유리하다는 LinkedList의 장점이 결합된 형태이다.

 

해시테이블에서 저장된 데이터를 가져오는 과정

1. 해시함수를 호출해서 key로 해시코드를 얻는다. 
2. 해시코드에 대응하는 LinkedList를 배열(해시테이블)에서 찾는다.
3. LinkedList에서 key와 일치하는 데이터를 찾는다.

 

 

 

 

HashMap의 주요 메서드

Object put(Object key, Object value)

데이터를 저장할 때 사용한다.

List와 Set은 add() 메서드를 사용했지만 Map은 put()을 사용한다.

HashMap map = new HashMap();
map.put("abcd", "1234");
map.put("ABCD", "5678");
System.out.println(map); //{ABCD=5678, abcd=1234}

map.put("ABCD", "9101112");
System.out.println(map); //{ABCD=9101112, abcd=1234}

map에 put() 메서드를 사용하여 키-값 쌍을 넣었다.

호출하면 key=value 형식으로 호출된다.

 

HashMap은 key값의 중복을 허용하지 않는다.

그래서 중복되는 key값이 들어오면 기존에 있던 key값에 덮어쓰기 되버린다. 

 

 

Object get(Object key)

매개변수로 넣은 key값에 해당하는 value 값을 반환한다.

HashMap map = new HashMap();
map.put("abcd", "1234");

System.out.println(map.get("abcd")); //1234

 

 

Set entrySet(), Set keySet()

entrySet() - 키-값 쌍의 집합을 반환한다.

keySet() - 키들의 집합을 반환한다.

HashMap map = new HashMap();
map.put("abcd", "1234");
map.put("efgh", "5678");

System.out.println(map.keySet()); //[efgh, abcd]
System.out.println(map.entrySet()); //[efgh=5678, abcd=1234]

 

 

Boolean containsKey(Object key), Boolean containsValue(Object value)

containsKey(key) - 객체에 key가 있으면 true를 없으면 false를 반환한다.

containsValue(value) - 객체에 value가 있으면 true를 없으면 false를 반환한다.

HashMap map = new HashMap();
map.put("abcd", "1234");

System.out.println(map.containsKey("abcd")); //true
System.out.println(map.containsValue("12345")); //false

 

 

 

예제

로그인 예제

ID와 PW를 확인하는 코드이다.

public class Test {
  public static void main(String[] args){
    HashMap map = new HashMap();
    map.put("abcd", "1234");
    map.put("efgh", "5678");
    
    Scanner s = new Scanner(System.in);
    
    while(true) {
      System.out.println("ID를 입력해주세요.");
      System.out.print("ID : ");
      String id = s.nextLine().trim(); //trim은 입력값의 앞뒤공백을 삭제한다.
      
      System.out.println("PW를 입력해주세요.");
      System.out.print("PW : ");
      String pw = s.nextLine().trim();
      
      if(!(map.containsKey(id))) {
        System.out.println("입력하신 ID는 존재하지 않습니다. 다시 입력해주세요.");
        continue;
      }
      if(!(map.get(id).equals(pw))) {
        System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요.");
      } else {
        System.out.println("로그인되었습니다.");
        break;
      }
    }
  }
}
// 결과

ID를 입력해주세요.
ID : ABCDE PW를 입력해주세요.
PW : 1234 입력하신 ID는 존재하지 않습니다. 다시 입력해주세요.
ID를 입력해주세요.
ID : abcd PW를 입력해주세요.
PW : 5678
비밀번호가 일치하지 않습니다. 다시 입력해주세요.
ID를 입력해주세요.
ID : abcd
PW를 입력해주세요.
PW : 1234
로그인되었습니다.

 

 

 

빈도수 확인 예제

요소들의 빈도수를 확인하는 예제이다.

public class Test {
  public static void main(String[] args){
    // 1~5 사이의 랜덤 값 20개를 data에 넣음 
    int[] data = new int[20];
    
    for(int i=0; i<20; i++) {
      int num = (int)(Math.random()*5)+1;
      data[i] = num;
    }
    
    // data배열을 돌면서 map에 같은 키값이 있으면 value에 +1, 없다면 map에 추가
    HashMap map = new HashMap();
    for(int i=0; i<data.length; i++) {
      if(map.containsKey(data[i])) {
        int value = (int)map.get(data[i]);
        map.put(data[i], value+1);
      } else {
        map.put(data[i], 1);
      }
    }
    
    // map을 읽어온다.
    Iterator it = map.entrySet().iterator();
    while(it.hasNext()) {
      Map.Entry entry = (Map.Entry)it.next();
      System.out.println(entry.getKey() + " : " + entry.getValue());
    }
  }
}

//결과
1 : 6
2 : 4
3 : 4
4 : 2
5 : 4

 

 

 

 

 

 

 

 

728x90
728x90