Considere o trecho de código abaixo:
HashSet hs = new HashSet();
hs.add("hi"); -- (1)
hs.add("hi"); -- (2)
hs.size()
fornecerá 1, pois HashSet
não permite duplicatas; portanto, apenas um elemento será armazenado.
Quero saber se adicionamos o elemento duplicado, então ele substitui o elemento anterior ou simplesmente não o adiciona?
Além disso, o que acontecerá usando HashMap
para o mesmo caso?
java
hashmap
duplicates
hashset
Anand
fonte
fonte
HashMap
para ver se okey
já existe antes de chamarput
o suportemap
?Set
, e isso nunca é substituído pelaput()
operação.Set
, mas acabei de perceber queput()
apenas substituirá o valor, não a chave. Nesse caso, é o mesmo valor colocado ao lado da chave novamente, o que pode ou não ser melhor do que verificar se a chave existe e coloca. De qualquer maneira, eu entendo como isso funciona.HashSet
ser implementado na forma deHashMap
. Difícil saber, a menos que você seja um dos desenvolvedores das classes.A primeira coisa que você precisa saber é que
HashSet
age como aSet
, o que significa que você adiciona seu objeto diretamente aoHashSet
e não pode conter duplicatas. Você acabou de adicionar seu valor diretamenteHashSet
.No entanto,
HashMap
é umMap
tipo. Isso significa que toda vez que você adiciona uma entrada, você adiciona um par de valor-chave.Em
HashMap
você pode ter valores duplicados, mas não chaves duplicadas. NaHashMap
nova entrada substituirá a antiga. A entrada mais recente será naHashMap
.Entendendo o link entre o HashMap e o HashSet:
Lembre-se,
HashMap
não pode ter chaves duplicadas. Nos bastidoresHashSet
usa umHashMap
.Quando você tenta adicionar qualquer objeto a
HashSet
, essa entrada é realmente armazenada como uma chave noHashMap
- o mesmoHashMap
que é usado nos bastidoresHashSet
. Como esse subjacenteHashMap
precisa de um par de valor-chave, um valor fictício é gerado para nós.Agora, quando você tentar inserir outro objeto duplicado no mesmo
HashSet
, ele tentará novamente inseri-lo como uma chave na parte deHashMap
baixo. No entanto,HashMap
não suporta duplicatas. Conseqüentemente,HashSet
ainda resultará em ter apenas um valor desse tipo. Como uma observação lateral, para cada chave duplicada, já que o valor gerado para nossa entrada no HashSet é algum valor aleatório / fictício, a chave não é substituída. ele será ignorado porque remover a chave e adicionar novamente a mesma chave (o valor fictício é o mesmo) não faria nenhum sentido.Resumo:
HashMap
permite duplicarvalues
, mas nãokeys
.HashSet
não pode conter duplicatas.Para saber se a adição de um objeto foi concluída com êxito ou não, você pode verificar o
boolean
valor retornado quando ligar.add()
e ver se ele retornatrue
oufalse
. Se retornoutrue
, foi inserido.fonte
HashMap allows duplicate values
O HashMap substitui o valor antigo pelo novo.Os documentos são bem claros sobre isso:
HashSet.add
não substitui:Mas irá substituir:
HashMap.put
fonte
É o caso do HashSet, NÃO o substitui.
Dos documentos:
http://docs.oracle.com/javase/6/docs/api/java/util/HashSet.html#add(E )
"Adiciona o elemento especificado a este conjunto se ele ainda não estiver presente. Mais formalmente, adiciona o elemento especificado e a esse conjunto se esse conjunto não contiver nenhum elemento e2, de modo que (e == null? E2 == null: e.equals ( e2)). Se este conjunto já contiver o elemento, a chamada deixará o conjunto inalterado e retornará falso. "
fonte
Me corrija se eu estiver errado, mas o que você está dizendo é que, com as strings, "Oi" == "Oi" nem sempre se torna realidade (porque elas não são necessariamente o mesmo objeto).
Porém, o motivo pelo qual você está obtendo uma resposta 1 é porque a JVM reutilizará objetos de cadeias sempre que possível. Nesse caso, a JVM está reutilizando o objeto de sequência e, portanto, substituindo o item no Hashmap / Hashset.
Mas você não tem esse comportamento garantido (porque pode ser um objeto de string diferente que tenha o mesmo valor "Oi"). O comportamento que você vê é apenas devido à otimização da JVM.
fonte
Você precisa verificar o método put no mapa Hash primeiro, pois o HashSet é feito pelo HashMap
fonte
Para dizer de maneira diferente: Quando você insere um par de valores-chave em um HashMap em que a chave já existe (em certo sentido, hashvalue () fornece o mesmo valor e und equal () é verdadeiro, mas os dois objetos ainda podem diferir de várias maneiras ), a chave não é substituída, mas o valor é substituído. A chave é usada apenas para obter o hashvalue () e encontrar o valor na tabela com ele. Como o HashSet usa as chaves de um HashMap e define valores arbitrários que realmente não importam (para o usuário), como resultado, os Elementos do conjunto também não são substituídos.
fonte
HashMap
basicamente contém oEntry
que contém subsequentementeKey(Object)
e.Value(Object)
InternamenteHashSet
sãoHashMap
eHashMap
substituem valores como alguns de vocês já apontaram .. mas ele realmente substitui as chaves ??? Não .. e esse é o truque aqui.HashMap
mantém seu valor como chave no subjacenteHashMap
e o valor é apenas um objeto fictício. Portanto, se você tentar reinserir o mesmo valor no HashMap (chave no mapa subjacente). Ele substitui o valor fictício e não a chave (Valor para HashSet).Veja o código abaixo para a classe HashSet:
Aqui e é o valor do HashSet, mas a chave do mapa subjacente. E a chave nunca são substituídas. Espero que eu seja capaz de limpar a confusão.
fonte