Map인터페이스를 통하여 key와 값(value)를 하나의 쌍으로 묶어서 저장하는 컬렉션 클래스를 구현
키 중복 불가
값 중복 허용
Set entrySet() : 키 - 값 쌍을 Map.Entry 타입의 객체로 저장한 set으로 반환
Map 인터페이스의 내부 인터페이스 (인터페이스 안의 인터페이스)
Map 인터페이스를 구현하기 위해서는 Map.Entry 인터페이스도 함께 구현해야 한다.
boolean equals(Object o) : 동일 Entry인지비교
Object getKey() : Entry 타입의 key객체 반환
Object getValue() : Entry 타입의 Value객체 반환
Object setValue(Object value) : Entry의 value 객체를 지정된 객체로 바꾼다
Hashtable과 HashMap은 구버전과 신버전, HashMap 사용이 권장됨
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;
}
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
링크드 리스트의 값을 검색하기 위해서는 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;
}