2012-01-15 16 views
4

WeakHashMapのエントリの削除を、そのキーのいずれかへのアクティブな参照がない場合、どのようにモデル化できますか?私は次のコードを持っている:WeakHashMapは廃止されたエントリを削除しません

WeakHashMap<Integer, String> weakMap = new WeakHashMap<Integer, String>(); 
Integer st1 = 5; 
Integer st2 = 6; 
String val = "BB"; 
weakMap.put(st1, "AA"); 
weakMap.put(st2, val); 
st1 = 10; 
//st1 = null; 
//System.gc(); 
for (Map.Entry<Integer, String> entry : map.entrySet()) { 
    System.out.println(entry.getKey() + " " + entry.getValue()); 
} 

出力は

6 BB 
5 AA 

常にあるがしかし、私は、それはまだ同じ出力を生成するだけ6 BB 私がコメントしdecomment場合でもラインを得ることを期待します。 WeakHashMapのキーにこのweakHashMap以外のどこかにアクティブな参照がない場合は、指定したキーのエントリを削除する必要があります。私は正しい?いいえ、正しい解決策を提案してください。

+4

System.gcはあなたが電話するときにgcをすることを保証しません。 – kosa

+0

ColinDが言ったようにコードを変更しました。私が作った試みでは(System.gc()で)動作します。それはすべての試みにおいて私が単に幸運であり、gcであることを意味するのでしょうか? – maks

+0

@maks:いくつかのJVMでは信頼できるが、他のJVMではそうすることはできないかもしれないし、いくつかのフラグに依存するかもしれない(私は特にそうではない)。しかし、それは必須ではありませんので、あなたが頼りにするべきではありません。 – ColinD

答えて

10

-128 127からInteger sは(それがautoboxed int秒間である、Integer.valueOfが使用されていると仮定して)キャッシュされるので、あなたのキーがガベージコレクトされることはありません。その範囲外の値を使用するか、Integer st1 = new Integer(5)を使用して、キャッシュされたオブジェクトを使用しないようにすることができます。

+0

ありがとうございます、私はその範囲外の数字で試して、それは動作します(平均削除)。ストリングスはどうですか?私はこれの前に文字列キーでテストしましたが、それも削除されていませんか? – maks

+0

@maks:おそらく 'String'リテラルを使用していました(たとえば、' String key = "key"; ')。それらも拘禁されています。 – ColinD

+0

「キャッシュされた」と言うと、ヒープに格納されていないということですか? – maks

1

-1000〜1000(またはその周辺)の整数オブジェクトが格納されます。つまり、オートボクシングとvalueOf()は、Integerに内部的に格納されたオブジェクトを返すため、ガベージコレクションは行われません。あなたがこれを行う場合は、意図した動作が表示されます。

Integer st1 = new Integer(5); 
Integer st2 = new Integer(6); 

... 

st1 = 10; 

System.gc(); 

...