본문 바로가기

Java

[Java] HashMap 키와 값

목차

  • HashMap 과 TreeMap
  • HashMap의 키(key)와 값(value)
  • 해싱(hashing) 기법
  • 해시테이블에서 저장된 데이터를 가져오는 과정
  • HashMap 주요 메서드
  • HashMap 예제

 

 

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

Map 인터페이스를 구현. 데이터를 키와 값의 쌍으로 저장(Key, value)

HashMap(동기화 X)은 Hashtable(동기화 O)의 new버전

 

남궁성 유튜브 출처: https://www.youtube.com/watch?v=oLH9Y8tD9Kw&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=132

 

 

 

HashMap

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

순서를 유지하려면, LinkedHashMap 클래스를 사용하면 된다.

 

 

TreeMap

범위 검색과 정렬에 유리한 컬렉션 클래스

HashMap보다 데이터 추가, 삭제에 시간이 더 걸림(비교를 한 후 저장)

 

 

HashMap의 키(key)와 값(value)

  • 해싱(hashing) 기법으로 데이터를 저장. 데이터가 많아도 검색이 빠르다.
  • Map 인터페이스를 구현. 데이터를 키와 값의 쌍으로 저장
  • key: 컬렉션 내의 키(key) 중에서 유일해야 한다.
  • value: 키와 달리 데이터의 중복을 허용한다.
  • 똑같은 키값이 들어오면 들어오지 않는 것이 아니라 value를 덮어써버리니 유의하자!
  • 키와 벨류 한쌍을 Entry라고 부른다.
Entry[] table;

class Entry {
    Object key;
    Object value;
}

 

버전이 올라가면서 코드가 바꼈다.

 

 

해싱(hashing) 기법

예시) 환자정보관리

출생년도로 환자서류 보관

key(75xxxxx-xxxxxx) 값을 넣으면 저장위치(인덱스)를 알려줌

 

함수를 이용해서 데이터를 저장하고 읽어오는 것

해시함수로 해시테이블에 데이터를 저장, 검색

해시 테이블은 배열과 링크드 리스트가 조합된 형태

배열의 장점(접근성), 링크드 리스트(변경에 유리) 장점을 합침

 

Hashtable, HashMap, HashSet 모두 hashCode( )를 사용한다.

@Override
public int hashCode() {
    // int has(Object... values); // 가변인자
    //return (name + age).hashCode();
    return Objects.hash(name, age);
}

 

 

 

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

  1. 키로 해시함수를 호출해서 해시코드(배열의 인덱스)를 얻는다(몇번 째 서랍에 넣어야 하는지).
  2. 해시코드(해시함수의 반환값)에 대응하는 링크드 리스트를 배열에서 찾는다.
  3. 링크드 리스트에서 키와 일치하는 데이터를 찾는다.
  • 해시함수는 같은 키에 대해 항상 같은 해시코드를 반환해야 한다.
  • 서로 다른 키일지라도 같은 값의 해시코드를 반환할 수도 있다.
  • 해시코드가 일치한다는 것은 같은 서랍안에 있다는 것
  • 이것은 괜찮다!! 서로 다른 키인데 같은 서랍안에도 있을 수 있기 때문이다.

 

 

HashMap 주요 메서드

남궁성 유튜브 출처: https://www.youtube.com/watch?v=el6cTtPHVRs&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=133

 

 

 

 

entrySet( ): key와 value 쌍들로 이루어진 Set를 반환

keySet( ): key 값만

values( ): value 값만

 

 

Object get(Object key): 특정 key 값을 주면 value값이 반환

getOrDefault(Object key, ObjectdefaultValue): Object key(찾는 키값)이 없을 때 ObjectdefaultValue(값)을 반환.

containsKey(Object key): 특정 key 값이 있는지

containsValue(Object value): 특정 value가 있는지

 

 

 

 

예제

 

public class MapEx1 {
    public static void main(String[] args) {

        HashMap map = new HashMap();
        map.put("myId", "1234");
        map.put("asdf", "1111");
        map.put("asdf", "1234");

        Scanner s = new Scanner(System.in);
        
        while (true) {
            System.out.println("id와 password를 입력해주세요");
            System.out.print("id: ");
            String id = s.nextLine().trim();
            System.out.print("password: ");
            String password = s.nextLine().trim();
            System.out.println();

            if (!map.containsKey(id)) { // key 중에 id가 있는지 확인
                System.out.println("아이디를 찾을 수 없습니다. 다시 입력해주세요");
                continue;
            }
            if (!map.get(id).equals(password)){ // get 메서드가 value를 반환 => password와 비교
                System.out.println("비밀번호가 일치하지 않습니다. 다시 입력해주세요");

            } else {
                System.out.println("id와 비밀번호가 일치합니다.");
                break;
            }
        }
    }
}

 

 

public class MapEx2 {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("김자바", 90);
        map.put("김자바", 100); // key값 일치 4개 저장
        map.put("이자바", 100);
        map.put("강자바", 80);
        map.put("안자바", 90);

        Set set = map.entrySet();
        Iterator it = set.iterator();

        while (it.hasNext()) {
            Map.Entry e = (Map.Entry)it.next();
            System.out.println("이름: " + e.getKey() + ", 점수: " + e.getValue());
        }

        set = map.keySet();
        System.out.println("참가자 명단: " + set);

        Collection values = map.values();
        it = values.iterator();

        int total = 0;

        while (it.hasNext()) {
            Integer i = (Integer)it.next();
            //total += i.intValue();
            total += i;
        }
        System.out.println("총점: " + total);
        System.out.println("평균: " + (double) total/ set.size());
        System.out.println("최고점수: " + Collections.max(values));
        System.out.println("최고점수: " + Collections.min(values));

    }
}

 

public class MapEx3 {
    public static void main(String[] args) {

        String[] data = {"A", "K", "A", "K", "D", "K", "A", "K", "K", "K", "Z", "D"};
        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);
            }
        }
        Iterator it = map.entrySet().iterator();

        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            int value = (int)entry.getValue();
            System.out.println(entry.getKey() + " : " + printBar('*', value) + " " + value);
        }

    }
    public static String printBar(char c, int value) {
        String format = "";
        for (int i = 0; i < value; i++) {
            format += c;
        }
        return format;
    }
}