자바 HashMap

HiroPark·2022년 8월 19일
1

Map 인터페이스

Map인터페이스를 통하여 key와 값(value)를 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스를 구현

  • 키 중복 불가

  • 값 중복 허용

  • Set entrySet() : 키 - 값 쌍을 Map.Entry 타입의 객체로 저장한 set으로 반환

Map.Entry 인터페이스

Map 인터페이스의 내부 인터페이스 (인터페이스 안의 인터페이스)

  • Map 인터페이스를 구현하기 위해서는 Map.Entry 인터페이스도 함께 구현해야 한다.

  • boolean equals(Object o) : 동일 Entry인지비교

  • Object getKey() : Entry 타입의 key객체 반환

  • Object getValue() : Entry 타입의 Value객체 반환

  • Object setValue(Object value) : Entry의 value 객체를 지정된 객체로 바꾼다

HashMap

Hashtable과 HashMap은 구버전과 신버전, HashMap 사용이 권장됨

  • 키와 값을 묶어서 하나로(entry) 저장
  • Hashing 사용

Map.entry를 구현한 HashMap의 Node

    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }
  • 키, 값을 함께 Node객체로 데이터를 관리한다.
  • 다음 노드를 가리키는 next 값을 가진다.

  1. 저장할 데이터의 키를 해시함수에 넣어서, 해싱을 거쳐 해시코드를 얻는다
  2. 해시코드를 통해 배열의 한 요소를 얻는다.
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
  1. 다시 그곳에 연결된 링크드 리스트에 값을 저장한다.

링크드 리스트의 값을 검색하기 위해서는 O(n)의 시간이 필요하기에, 특정 링크드 리스트의 크기가 커지지 않고 균일하게 커질 수 있도록 하여야 한다.

위의 코드에서 해시함수로 사용하는 Objects의 hashcode()함수이다.

public static int hashCode(Object o) {
        return o != null ? o.hashCode() : 0;
    }

코드를 확인하면 , Object의 hashCode() 를 사용하고 있음을 알 수 있다.

이 hashCode()는 객체의 주소를 사용하여 해시코드를 만들어내기에, 각 객체에 대해 hashcode()를 호출한 결과가 서로 유일하다.
단, String클래스는 오버라이딩을 통해 문자열의 내용 으로 해시코드를 만들어 내기에, 인스턴스가 달라도 문자열의 내용이 같으면 같은 hashcode를 반환한다.

HashMap은
1. 서로 다른 두 객체에 대해 equals()로 비교한 결과가 true

public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
  1. 두 객체의 hashcode()의 반환값이 같아야
    같은 객체로 인식한다.
profile
https://de-vlog.tistory.com/ 이사중입니다

0개의 댓글