8

LinkedHashMapについて読んだところ、説明から(非常に興味深いものの)、実際に内部でどのように機能するのか理解できませんでした。HashMapちなみに、私はJavaで動作する方法を知っています。
だから私はソースをレビューしましたが、それでもそれがどのように機能するのか理解できません。おそらく、この場合、私はOOPの基本的なことを理解していないので、我慢してください。
私を混乱させる部分を要約すると、次のようになります
LinkedHashMapデリゲートはすべての呼び出しをその親に委任しますHashMap。内部的には、のロジックを実装しているように見えるさまざまなメソッドを実装するためにを
オーバーライドしますが 、実際は基本クラスのテーブル内にあります。HashMap.EntryrecordAccessrecordRemovalLinkedHashMap
EntriesHashMapのテーブルをインスタンス化し、のテーブルをインスタンス化しHashMap.EntryませんLinkedHashMap.Entry。ですから、いろいろなものなどが実際に
どのように呼ばれているのかわかりません。 それで、誰かが私がここで何が起こっているのかを理解するのを手伝ってくれるでしょうか? どういうわけか、によって作成されたテーブルのタイプであると考えるのは正しいですか?しかし、どのように? recordAccessrecordRemove

LinkedHashedMap.EntryHashMap

更新:
私の質問は、どのようrecordAccessに呼び出されているかです。HashMapShengyuan Lu(+1)の理由で失敗し たの派生バージョンを使用したこれに関する私の実験-そこに私の悪い

更新:
私が試した次のことは、何をしているのかと同じです(私は思います)LinkedHashMap

package delete;  

public class Base<T> {  

    Entry<T>[] table;  
    int idx = 0;  
    @SuppressWarnings("unchecked")  
    public Base(){  
        System.out.println("In base");  
        table = new Entry[10];  
    }

    public void add(T x){  
        table[idx] = new Entry(x);  
        table[idx].doSomething();  
    }  

    static class Entry<T>{  
        T value;  

        Entry(T x){  
            this.value = x;  
            System.out.println("Entry::Base");  
        }

        void doSomething(){  
            System.out.println("In Entry base, doing something");  
        }  
    }  

}  




public class Derived<T> extends Base<T> {  

    static class Entry<T> extends Base.Entry<T>{  

        Entry(T x) {  
            super(x);  
            System.out.println("In Entry derived");  
        }  

        int val;  

        @Override  
        void doSomething() {  
            System.out.println("In Entry derived doing something really smart!");  
        }       
    }  

    /**
     * @param args
     */
    public static void main(String[] args) {  

        Base<String> b = new Derived<String>();  
        b.add("Test string");  

    }  

}  

しかし、それは印刷します:

In base  
Entry::Base     
In Entry base, doing something    

したがって、派生Entryが呼び出されることはありません。
私の例はどういうわけか違うのですか?これがどのように機能するのか理解できませんLinkedHashMap

4

2 に答える 2

4

MyLinkedHashMappackage の下で定義するjava.utilと、コンパイルされます;)

HashMap.HashEntryパッケージの可視性のためです。

プラス:

あなたが困惑しているのは、LinkedHashMap.EntryHashMap.Entryだと思います。ポイントは、LinkedHashMap.Entry が HashMap.Entry であることです。実はHashMap.table は LinkedHashMapに LinkedHashMap.Entry を格納しています。

recordAccessとに関してはrecordRemoval、どちらも HashMap.Entry バージョンをオーバーライドします。LinkedHashMap と HashMap の両方で参照を見つけることができます。

ここにコメントをマージしてください:サンプル コードは実装と同じではありません。代わりにLinkedHashMap参照してください。LinkedHashMap.addEntry()

于 2012-06-03T12:41:39.690 に答える
2

Ctrl+F は、特に一度に複数のファイルを検索できる場合に役立ちます。recordAccessアクセス/作成されたエントリで、マップの メソッドputとメソッドによって呼び出されます。get(呼び出しはHashMap.putHashMap.putForNullKeyおよびにありLinkedHashMap.getます。) これは、ブール値のパラメーターを取り、それに渡される LinkedHashMap のコンストラクターを使用する場合にのみ関連しますtrue。つまり、マップをタッチすると、タッチしたエントリが内部リンク リストの先頭に移動します。

ドキュメントの引用:

リンクされたハッシュ マップを作成するための特別なコンストラクターが提供されます。この反復順序は、そのエントリが最後にアクセスされた順序 (最も古いアクセスから最も最近のアクセスの順序 (アクセス順序) です) です。この種のマップは、LRU キャッシュの構築に適しています。put メソッドまたは get メソッドを呼び出すと、対応するエントリにアクセスできます (呼び出しの完了後にエントリが存在すると仮定します)。putAll メソッドは、指定されたマップのエントリ セット イテレータによってキーと値のマッピングが提供される順序で、指定されたマップ内のマッピングごとに 1 つのエントリ アクセスを生成します。エントリ アクセスを生成する他のメソッドはありません。特に、コレクション ビューに対する操作は、バッキング マップの反復の順序には影響しません。

removeEldestEntry(Map.Entry) メソッドをオーバーライドして、新しいマッピングがマップに追加されたときに古いマッピングを自動的に削除するポリシーを課すことができます。

同様recordRemovalに と から呼び出されHashMap.removeEntryForKeyますHashMap.removeMapping

于 2012-06-03T13:08:41.997 に答える