1. Hashtable은 Dictionary의 하위 클래스입니다.
다음과 같이 코드 코드를 복사합니다 .
공개 클래스 Hashtable<K,V>
Dictionary<K,V> 확장
Map<K,V>, Cloneable, java.io.Serialized를 구현합니다.
해시맵:
다음과 같이 코드 코드를 복사합니다 .
공개 클래스 HashMap<K,V>
AbstractMap<K,V> 확장
Map<K,V> 구현, 복제 가능, 직렬화 가능
HashMap과 Hashtable은 모두 Map 인터페이스의 구현 클래스입니다.
2. Hashtable의 메소드는 동기()이지만 HashMap의 메소드는 기본적으로 동기가 아닙니다. 즉, 멀티 스레드 애플리케이션에서는 HashTable을 특별한 작업 없이 안전하게 사용할 수 있지만 HashMap의 경우 추가적인 동기화 메커니즘이 필요합니다. 그러나 HashMap의 동기화 문제는 컬렉션의 정적 메소드를 통해 해결할 수 있습니다.
다음과 같이 코드 코드를 복사합니다 .
공개 정적 <K,V> 맵<K,V> 동기화된Map(Map<K,V>m)
이 메소드는 동기화된 맵을 반환합니다. 이는 반환된 맵이 스레드로부터 안전하다는 것을 의미합니다. 반환된 맵을 반복할 때 반환된 맵에서 수동으로 동기화해야 한다는 점에 유의해야 합니다. 그렇지 않으면 정의되지 않은 동작이 발생하게 됩니다.
다음과 같이 코드 코드를 복사합니다 .
맵 m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // 동기화된 블록에 있을 필요는 없습니다.
...
동기화(m) { // s가 아닌 m에서 동기화 중입니다!
Iterator i = s.iterator(); // 동기화된 블록에 있어야 합니다.
동안(i.hasNext())
foo(i.next());
}
3. HashMap에서는 null을 키로 사용할 수 있으며 해당 키는 해당 값이 null인 하나 이상의 키만 있을 수 있습니다. get() 메서드가 null 값을 반환하는 경우 해당 키가 HashMap에 존재하지 않거나 해당 키에 해당하는 값이 null임을 의미할 수도 있습니다. 따라서 HashMap에서는 get() 메소드를 사용하여 HashMap에 특정 키가 존재하는지 확인할 수 없고, containKey() 메소드를 사용하여 확인해야 합니다. Hashtable의 키 값은 null일 수 없습니다. 그렇지 않으면 java.lang.NullPointerException입니다.
4.HashTable은 Enumeration을 사용하고 HashMap은 Iterator를 사용합니다.
위의 내용은 표면적인 차이점일 뿐이며 구현 방식도 매우 다릅니다.
5. HashTable의 해시 배열의 기본 크기는 11이고, 증가 방식은 old*2+1입니다. HashMap의 해시 배열의 기본 크기는 16이고 지수는 2여야 합니다.
6. 해시값의 사용이 다릅니다. HashTable은 객체의 hashCode를 직접 사용합니다.
다음과 같이 코드 코드를 복사합니다 .
int hash = key.hashCode();
int index = (해시 & 0x7FFFFFFFF) % tab.length;
HashMap은 해시 값을 다시 계산하고 HashMap의 put 메소드와 같이 모듈러스 대신 AND를 사용합니다.
다음과 같이 코드 코드를 복사합니다 .
공개 V put(K 키, V 값) {
if (키 == null)
return putForNullKey(값);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = 테이블[i]; e != null; e = e.next) {
객체 k;
if (e.hash == hash && ((k = e.key) == 키 || key.equals(k))) {
V oldValue = e.value;
e.값 = 값;
e.recordAccess(this);
oldValue를 반환합니다.
}
}
모드카운트++;
addEntry(해시, 키, 값, i);
null을 반환;
}
다음과 같이 코드 코드를 복사합니다 .
정적 int 해시(int h) {
// 이 함수는 해시코드의 차이만 보장합니다.
// 각 비트 위치의 상수 배수는 경계가 있습니다.
// 충돌 횟수(기본 로드 팩터에서는 약 8).
h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);
}
다음과 같이 코드 코드를 복사합니다 .
static int indexFor(int h, int length) {
h & (길이-1)을 반환합니다.
}