[데이터 구조] - jdk 1.8 에서 HashMap 소스 코드 분석
9421 단어 [구조 설계][데이터 구조 와 알고리즘]
Hashmap 는 자바 집합 에서 비교적 중요 한 집합 프레임 워 크 입 니 다. 특징: 키 값 은 저장 소, key 는 null 로 검색 속도 가 빠 르 지만 스 레 드 는 안전 하지 않 습 니 다.
hashMap 의 클래스 관계
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
hashMap 의 데이터 구조
jdk 1.6 에서 HashMap 은 table 배열 (비트 통) + 단 방향 링크 로 이 루어 집 니 다. 돌, 같은 hash 값 의 링크 는 모두 하나의 링크 에 저 장 됩 니 다.그러나 한 통 에 있 는 요소 가 비교적 많다. 즉, hash 값 이 같은 요소 가 많 을 때 key 값 을 통 해 순서대로 찾 는 효율 이 비교적 낮다.
한편, JDK 1.8 에서 HashMap 은 비트 통 + 링크 + 레 드 블랙 트 리 로 이 루어 졌 고 링크 길이 가 한도 값 (8) 을 초과 할 때 링크 를 레 드 블랙 트 리 로 전환 하여 검색 시간 을 크게 줄 였 다.
알고리즘 구현
1. 우선 hash 알고리즘
hash 알고리즘 정밀 설명, 링크 전송 문
public native int hashCode();
static final int hash(Object key) {
int h;
// , 0
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
2. node 노드
static class Node implements Map.Entry {
final int hash; //hash hash for key
final K key; //key
V value; //value
Node next;//
3. 알고리즘 삽입
키 가 비어 있 을 때 jdk 1.6 의 방법 은 putForNullKey 입 니 다. 1.8 에서 정책 을 찾 지 못 했 습 니 다.
public V put(K key, V value) {
// hash , table
return putVal(hash(key), key, value, false, true);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
boolean evict) {
Node[] tab; Node p; int n, i;
// tab 0, resize()
if ((tab = table) == null || (n = tab.length) == 0)
n = (tab = resize()).length;
//(n - 1) & hash put , , put
if ((p = tab[i = (n - 1) & hash]) == null)
tab[i] = newNode(hash, key, value, null);
else {
Node e; K k;
if (p.hash == hash &&
((k = p.key) == key || (key != null && key.equals(k))))
e = p;
// AVL , , 。
//
else if (p instanceof TreeNode)
e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value);
else {
//
for (int binCount = 0; ; ++binCount) {
//p ,
if ((e = p.next) == null) {
//e , key ,
p.next = newNode(hash, key, value, null);
// , , ,
if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
treeifyBin(tab, hash);
break;
}
// null==null
if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))
break;
p = e;// p
}
}
// hash key Value
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
}
++modCount;
if (++size > threshold)
resize();
afterNodeInsertion(evict);
return null;
}
찾다
index,
// Key
// object
*
public V get(Object key) {
Node e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
*
* final Node getNode(int hash, Object key) {
Node[] tab; Node first, e; int n; K k;
//hash & (length-1) ,
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)// , ,
return ((TreeNode)first).getTreeNode(hash, key);
do {// , table key
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
*
*/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[Spring Boot] Mybatis Plus 3. X 조건 조회X 가 조 회 를 실현 하 는 방식 이 다르다 는 것 을 알 고 있 습 니 다. 여기 서 사용 하 는 것 은 Query Wrapper 구조 조회 조건 입 니 다. eq 를 사용 하여 해당 항목 의 번호 조건 을 실현...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.