자바 맵 집합 프레임 워 크 의 링크 드 HashMap

1.LinkedHashMap 개요:
링크 드 하 쉬 맵 은 하 쉬 맵 의 하위 클래스 로 삽입 순 서 를 유지 합 니 다.출력 순서 가 입력 과 같 으 면 링크 드 하 쉬 맵 을 선택 하 십시오.
   링크 드 HashMap 은 Map 인터페이스의 해시 표 와 링크 목록 이 실현 되 고 예측 가능 한 교체 순서 가 있 습 니 다.이것 은 선택 할 수 있 는 모든 맵 작업 을 제공 하고 null 값 과 null 키 를 사용 할 수 있 습 니 다.비 치 는 순 서 를 보장 하지 않 습 니 다.특히 이 순 서 는 영원히 변 하지 않 습 니 다.   링크 드 HashMap 실현 과 HashMap 의 차이 점 은 후자 가 모든 항목 에서 실행 되 는 이중 링크 목록 을 유지 하고 있다 는 것 이다.이 링크 목록 은 교체 순 서 를 정의 합 니 다.이 교체 순 서 는 삽입 순서 나 방문 순서 일 수 있 습 니 다.   이 실현 은 동기 화 되 지 않 음 을 주의 하 세 요.여러 스 레 드 가 링크 의 해시 맵 에 동시에 접근 하면 최소한 하나의 스 레 드 가 구조 적 으로 이 맵 을 수정 하면 외부 동기 화 를 유지 해 야 합 니 다.
 
링크 에 있 는 요소 의 순서 에 따라 삽입 순서에 따라 링크 와 방문 순서(get 방법 호출)에 따라 링크 로 나 눌 수 있 습 니 다.  
기본 값 은 삽입 순서에 따라 정렬 합 니 다.방문 순서에 따라 정렬 할 것 을 지정 하면 get 방법 을 호출 한 후에 이번 방문 요 소 를 링크 끝 에 옮 기 고 계속 방문 하면 방문 순서에 따라 정렬 하 는 링크 를 만 들 수 있 습 니 다. removeEldestEntry 방법 을 다시 쓸 수 있 습 니 다.true 값 이 지정 한 삽입 요 소 를 되 돌려 줄 때 가장 오래된 요 소 를 제거 할 수 있 습 니 다. 
2.LinkedHashMap 인터페이스
public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
{

  LinkedHashMap 에서 사용 하 는 hash 알고리즘 은 HashMap 과 같 지만 배열 에 저 장 된 요소 Entry 를 다시 정의 합 니 다.이 Entry 는 현재 대상 의 인용 을 저장 하 는 것 외 에 이전 요소 before 와 다음 요소 after 의 인용 도 저장 하여 해시 표를 바탕 으로 양 방향 링크 목록 을 구성 합 니 다.
linedHashMap 인터페이스의 구성원 변수
  /**
     * The head of the doubly linked list.
     */
    private transient Entry<K,V> header;

    /**
     * The iteration ordering method for this linked hash map: <tt>true</tt>
     * for access-order, <tt>false</tt> for insertion-order.
     *
     * @serial
     */
    private final boolean accessOrder;

Entryheader 양 방향 링크 의 헤더 요소
accessOrder:true 는 방문 순서에 따라 교체 하고 false 는 삽입 순서에 따라 표시 합 니 다. 
LinkedHashMap 의 Entry
HashMap 의 Entry
 /**
     * LinkedHashMap entry.
     */
    private static class Entry<K,V> extends HashMap.Entry<K,V> {
        // These fields comprise the doubly linked list used for iteration.
        Entry<K,V> before, after;

        Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
            super(hash, key, value, next);
        }
위의 양 끝 코드 를 보면 링크 드 HashMap 의 Entry 요 소 는 HashMap 의 Entry 를 계승 하고 이전 요소 의 before 와 다음 요 소 를 저장 한 after 를 알 수 있 습 니 다.
LinkedHashMap 은 부모 클래스 HashMap 의 put 방법 을 다시 쓰 지 않 고 부모 클래스 HashMap 의 put 방법 으로 호출 된 하위 방법 void recordAccess(HashMap m)를 다시 썼 습 니 다.   ,void addEntry(int hash,K key,V value,int bucketIndex)와 void createEntry(int hash,K key,V value,int bucketIndex)는 자신 만 의 양 방향 링크 목록 을 제공 하여 LinkedHashMap 의 저장 요 소 를 실현 하 는 방법 을 제공 합 니 다.
static class Entry<K,V> implements Map.Entry<K,V> {  
        final K key;  
        V value;  
        Entry<K,V> next;  
        final int hash;  
  
        Entry(int h, K k, V v, Entry<K,V> n) {  
            value = v;  
            next = n;  
            key = k;  
            hash = h;  
        }  
}
  /**
         * Inserts this entry before the specified existing entry in the list.
         */
        private void addBefore(Entry<K,V> existingEntry) {
            after  = existingEntry;
            before = existingEntry.before;
            before.after = this;
            after.before = this;
        }

        /**
         * This method is invoked by the superclass whenever the value
         * of a pre-existing entry is read by Map.get or modified by Map.set.
         * If the enclosing Map is access-ordered, it moves the entry
         * to the end of the list; otherwise, it does nothing.
         */
        void recordAccess(HashMap<K,V> m) {
            LinkedHashMap<K,V> lm = (LinkedHashMap<K,V>)m;
            if (lm.accessOrder) {
                lm.modCount++;
                remove();
                addBefore(lm.header);
            }
        }

HashMap 의 저장 방법 비교
예:
  /**
     * This override differs from addEntry in that it doesn't resize the
     * table or remove the eldest entry.
     */
    void createEntry(int hash, K key, V value, int bucketIndex) {
        HashMap.Entry<K,V> old = table[bucketIndex];
        Entry<K,V> e = new Entry<>(hash, key, value, old);
        table[bucketIndex] = e;
        e.addBefore(header);
        size++;
    }

마지막 으로 링크 드 HashMap 의 원본 코드 를 동봉 합 니 다.
public V put(K key, V value) {  
        if (key == null)  
            return putForNullKey(value);  
        int hash = hash(key.hashCode());  
        int i = indexFor(hash, table.length);  
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {  
            Object k;  
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {  
                V oldValue = e.value;  
                e.value = value;  
                e.recordAccess(this);  
                return oldValue;  
            }  
        }  
  
        modCount++;  
        addEntry(hash, key, value, i);  
        return null;  
    }  

좋은 웹페이지 즐겨찾기