자바 소스 분석 링크 드 HashMap
6124 단어 Java집합 하 다.LinkedHashMap
먼저 저장 요소 의 구 조 를 살 펴 보 자.
static class Entry<K,V> extends HashMap.Node<K,V> {
Entry<K,V> before, after;
Entry(int hash, K key, V value, Node<K,V> next) {
super(hash, key, value, next);
}
}
이 Entry 는 HashMap 에서 인 용 된 적 이 있 는데 주로 LinkedHashMap 도 트 리 화 를 지원 하기 위해 서 입 니 다.여기 서 는 원 소 를 저장 하 는 데 쓰 인 다.
// , AccessOrder
transient LinkedHashMap.Entry<K,V> head;
// , AccessOrder
transient LinkedHashMap.Entry<K,V> tail;
// true ,false
final boolean accessOrder;
구조 함수링크 드 HashMap 의 구조 함수 에 대해 우 리 는 하나만 주목 합 니 다.다른 것 은 모두 HashMap 과 유사 합 니 다.다만 accessOrder 를 false 로 설정 합 니 다.위 문서 에서 말 했 듯 이 initial Capacity 는 HashMap 에서 만큼 중요 하지 않 습 니 다.링크 는 배열 처럼 충분 한 공간 을 먼저 밝 혀 야 하지 않 기 때 문 입 니 다.아래 의 이 구조 함 수 는 접근 순 서 를 지원 합 니 다.
// , AccessOrder
transient LinkedHashMap.Entry<K,V> head;
// , AccessOrder
transient LinkedHashMap.Entry<K,V> tail;
// true ,false
final boolean accessOrder;
3.중요 한 방법링크 드 하 쉬 맵 은 더 이상 삭제 하고 고 치 는 방법 을 실현 하지 않 고 하 쉬 맵 을 복사 하 는 과정 에서 정 의 된 몇 가지 방법 으로 이 루어 졌 다.이에 익숙 하지 않 은 것 은 지난 HashMap 분석 에 관 한 글 을 보 거나 HashMap 의 소스 코드 를 대조 해 볼 수 있다.
1.요소 삽입
HashMap 을 삽입 할 때 new Node 를 호출 하여 노드 를 새로 만 들 거나 replacementNode 를 통 해 값 을 바 꿉 니 다.트 리 화 할 때 도 두 가지 대응 하 는 방법 이 있 는데 그것 이 바로 new TreeNode 와 replacement TreeNode 이다.완 료 된 후에 after NodeInsertion 방법 도 호출 되 었 습 니 다.이 방법 은 우리 가 삽입 이 완 료 된 후에 일 을 할 수 있 도록 해 주 었 습 니 다.기본 값 은 비어 있 습 니 다.
분석 을 편리 하 게 하기 위해 우 리 는 HashMap 의 실현 과 LinkedHashMap 의 실현 을 비교 하여 그것 이 어떻게 하 는 지 알 아 볼 것 이다.
// HashMap
Node<K, V> newNode(int hash, K key, V value, Node<K, V> next) {
return new Node<>(hash, key, value, next);
}
// LinkedHashMap
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
LinkedHashMap.Entry<K,V> p =
new LinkedHashMap.Entry<K,V>(hash, key, value, e);
linkNodeLast(p);
return p;
}
// HashMap
Node<K, V> replacementNode(Node<K, V> p, Node<K, V> next) {
return new Node<>(p.hash, p.key, p.value, next);
}
// LinkedHashMap
Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) {
LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p;
LinkedHashMap.Entry<K,V> t =
new LinkedHashMap.Entry<K,V>(q.hash, q.key, q.value, next);
transferLinks(q, t);
return t;
}
// newTreeNode replacementTreeNode
상기 비 교 를 통 해 알 수 있 듯 이 링크 드 HashMap 은 새로 추 가 했 을 때 링크 Node Last 를 호출 했 고 다시 교체 할 때 transferLinks 를 호출 했다.다음은 이 두 가지 방법의 실현 이다.
//
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
LinkedHashMap.Entry<K,V> last = tail;
tail = p;
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
}
// dst src
private void transferLinks(LinkedHashMap.Entry<K,V> src,
LinkedHashMap.Entry<K,V> dst) {
LinkedHashMap.Entry<K,V> b = dst.before = src.before;
LinkedHashMap.Entry<K,V> a = dst.after = src.after;
if (b == null)
head = dst;
else
b.after = dst;
if (a == null)
tail = dst;
else
a.before = dst;
}
마지막 으로 after Node Insertion 이 어떤 일 을 했 는 지 살 펴 보 자.
// evict HashMap , false
void afterNodeInsertion(boolean evict) { // possibly remove eldest
LinkedHashMap.Entry<K,V> first;
//
if (evict && (first = head) != null && removeEldestEntry(first)) {
K key = first.key;
// , head
removeNode(hash(key), key, null, false, true);
}
}
removeEldestEntry 는 요 소 를 삽입 할 때 가장 오래된 요 소 를 자동 으로 삭제 하려 면 복사 하 는 방법 입 니 다.기본 값 은 다음 과 같 습 니 다.
protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
return false;
}
2.조회접근 순 서 를 지원 해 야 하기 때문에 요 소 를 가 져 오 는 방법 과 HashMap 도 다르다.다음은 그 실현 을 살 펴 보 자.
public V get(Object key) {
Node<K,V> e;
if ((e = getNode(hash(key), key)) == null)
return null;
if (accessOrder)
// ,
afterNodeAccess(e);
return e.value;
}
getNode 방법 은 HashMap 에서 이 루어 졌 기 때문에 이것 은 HashMap 을 포장 하 는 방법 이 고 after Node Access 를 추 가 했 습 니 다.이 는 다음 과 같 습 니 다.
void afterNodeAccess(Node<K,V> e) { // move node to last
LinkedHashMap.Entry<K,V> last;
// e
if (accessOrder && (last = tail) != e) {
// p e,b ,a
LinkedHashMap.Entry<K,V> p =
(LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
// e , after
p.after = null;
// e , b a
if (b == null)
head = a;
else
b.after = a;
if (a != null)
a.before = b;
else
last = b;
// e
if (last == null)
head = p;
else {
p.before = last;
last.after = p;
}
tail = p;
++modCount;
}
}
자바 소스 코드 분석 에 관 한 링크 드 하 쉬 맵 에 관 한 글 은 여기까지 입 니 다.더 많은 자바 링크 드 하 쉬 맵 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.