Um dia desses estava lendo os documentos do Java5, e olhando a Interface Map fiquei interessado pelas duas classes citadas no título. Alguém já as utilizou e percebeu alguma característica além da colocada na documentação, tipo tamanho do objeto na memória, performance etc? Os objetos dentro da WeakHashMap são eleitos para o recolhimento do GC normalmente?
As chaves são eleitas para GC e, quando isso acontece, o valor associado a ela é retirado do mapa. Para cada chave é usado uma WeakReference.
Uma classe que puxei de uma biblioteca não tinha um determinado atributo que eu precisava. Então criei um mapa desses que mapeava os objetos dessa classe ao atributo adicional. O interessante é que, quando a classe era elegível para GC, eu não precisava me preocupar em remover nada do mapa, já que a própria weakreference tratava disso para mim.
maquiavelbona
No WeakHashMap, se uma chave for, por exemplo, uma String “ref1” e o uso dela seja através do recebimento de parâmetros, que podem ser “ref1” ou nunca serem, a referência do valor pode ser liberada antecipadamente? No caso de utilizar um Iterator, tem como eu forçar que a chave não seja recolhida?
No IdentityHashMap, a captação do conteúdo através do uso da referência como chave tem algum ganho significativo? Fiz micro testes aqui e não vi diferença perceptível.
Valeu e até!
Obs.: Editado para melhor entendimento e complementação.
ViniGodoy
A única maneira de se evitar que uma chave de um WeakHashMap não seja recolhida é criando uma referência forte para essa mesma chave.
Mas, pense bem na sua pergunta e verá que não tem muita razão para isso. Se você quer evitar remoção das chaves, ou é porque ainda tem uma referência para o objeto, ou é porque não deveria estar usando um WeakHashMap.
Também não vi muita razão para usar um Identity Hash Map. Não creio que a razão para existência dessa classe seja performance, até porque esse não é um problema críticos dos maps.
maquiavelbona
É que na própria documentação fala que se usares um Iterator para percorrer o WeakHashMap e houver uma alteração ( do tipo a chave ser coletada ), ele vai lançar uma ConcurrentModificationException e eu queria que só naquele momento, a chave não fosse coletada sem ter que fazer uso desnecessário.
O único exemplo de uso do IdentityHashMap que eu vi foi o contador de memória apresentado nesse fórum.
Obrigado e até!
sergiotaborda
ViniGodoy:
Também não vi muita razão para usar um Identity Hash Map. Não creio que a razão para existência dessa classe seja performance, até porque esse não é um problema críticos dos maps.
Como o ppr javadoc fala essa classe tem um fim especifico. Antigamente poderia ser usada para implementar um mapa de enums , quando se usava o padrão enum pre-java-5, já que cada valor é único a comparação usando == é suficiente. Hoje em dia tem um mapa especial para enums pós-java-5 então não precisa usar IdentityMap e ele acaba servindo apenas para o que o javadoc fala.
ViniGodoy
Já vi outras razões, mas não me convenceram muito também.
Como por exemplo, montar um mapa quando as chaves apresentam hash próximo (no caso, com chaves de classes diferentes, cujo resultado do cálculo gera muita colisão), ou então para situações onde as chaves recaem em alguma condição de igualdade com equals (e, nesse caso, teriam hash iguais).
Ainda assim, nunca me deparei com uma situação desses tipos.