Classe IdentityHashMap em Java

Classe IdentityHashMap em Java

O IdentidadeHashMap implementos Mapa interface usando Tabela hash usando igualdade de referência no lugar da igualdade de objeto ao comparar chaves (e valores). Esta classe não é uma implementação de mapa de uso geral. Embora esta classe implemente a interface Map, ela viola intencionalmente o contrato geral do Map, que exige o uso do método equals() ao comparar objetos. Esta classe é utilizada quando o usuário requer que os objetos sejam comparados via referência. Pertence a java.util pacote.

Recursos do IdentityHashMap

  • Segue a igualdade de referência em vez de usar o método equals(), ele usa o operador ==.
  • Não está sincronizado e deve ser sincronizado externamente.
  • Iteradores são lançados com falha rápida ConcurrentModificationException na tentativa de modificar durante a iteração.
  • Esta classe fornece desempenho em tempo constante para as operações básicas (get e put), assumindo que a função hash de identidade do sistema (System.identityHashCode(Object)) dispersa os elementos adequadamente entre os buckets. IdentityHashMap não usa o método hashCode() em vez disso, usa o método System.identityHashCode(). Esta é uma diferença significativa porque agora você pode usar objetos mutáveis ​​como chave no Mapa cujo código hash provavelmente mudará quando o mapeamento for armazenado dentro do IdentityHashMap.

Declaração:

classe pública IdentityHashMap estende AbstractMap implementa Mapa Serializável Clonável 
 

Aqui K é o tipo de objeto chave e V é o valor Tipo de objeto.

Em Java IdentityHashMap é uma classe que implementa a interface Map. É semelhante à classe HashMap, com a principal diferença sendo que IdentityHashMap usa igualdade de referência em vez de igualdade de objeto ao comparar chaves.

Enquanto HashMap usa o método equals() para comparar as chaves, IdentityHashMap usa o operador == para comparar as chaves. Isso significa que em um IdentityHashMap duas chaves são consideradas iguais se e somente se forem o mesmo objeto, em vez de serem iguais em termos de conteúdo.

Aqui está um exemplo de como você pode usar um IdentityHashMap em Java:

Java
   import     java.util.IdentityHashMap  ;   public     class   Example     {      public     static     void     main  (  String  []     args  )     {      IdentityHashMap   <  String       Integer  >     identityHashMap     =     new     IdentityHashMap   <>  ();      identityHashMap  .  put  (  'A'       1  );      identityHashMap  .  put  (  new     String  (  'A'  )     2  );      System  .  out  .  println  (  identityHashMap  .  size  ());     // 2      System  .  out  .  println  (  identityHashMap  .  get  (  'A'  ));     // 1      }   }   

saída;

1

A classe IdentityHashMap em Java é uma implementação baseada em tabela hash da interface Map que usa igualdade de referência no lugar da igualdade de objeto ao comparar chaves (e valores).

Vantagens de usar IdentityHashMap em vez de HashMap:

  1. Pesquisas mais rápidas: como o IdentityHashMap usa igualdade de referência para comparação, é mais rápido para pesquisas em comparação com o HashMap, que usa igualdade de objetos.
  2. Útil para comparar instâncias de objetos: IdentityHashMap é útil em situações em que você deseja comparar instâncias de objetos em vez de valores de objetos.

Desvantagens de usar IdentityHashMap:

  1. Usa mais memória: IdentityHashMap usa mais memória em comparação com HashMap, pois precisa armazenar a referência ao objeto.
  2. Não é adequado para todos os casos de uso: IdentityHashMap não é adequado para todos os casos de uso e deve ser usado com cautela, pois pode levar a um comportamento inesperado em determinadas situações.

 

A hierarquia do IdentityHashMap

IdentityHashMap em Java

Ele implementa Serializável Clonável Mapa interfaces e extensões ResumoMapa aula.

Exemplo:

Java
   // Java code to demonstrate IdentityHashMap    import     java.util.Map  ;   import     java.util.HashMap  ;   import     java.util.IdentityHashMap  ;   public     class   IdentityHashMapExample      {      public     static     void     main  (  String  []     args  )         {      // creating an instance of IdentityHashMap      Map   <  String       String  >     ihm     =     new     IdentityHashMap   <>  ();      // Putting key and value pair      // in a IdentityHashMap Object      ihm  .  put  (  'ihmkey'    'ihmvalue'  );         ihm  .  put  (  new     String  (  'ihmkey'  )  'ihmvalue1'  );             // ihm.size() will print 2 since it       // compares the objects by reference      System  .  out  .  println  (  'Size of IdentityHashMap--'  +  ihm  .  size  ());          }   }   

Saída
Size of IdentityHashMap--2  

Construtores de IdentityHashMap

Podemos criar uma instância de IdentidadeHashMap de duas maneiras:

IdentityHashMap  ihm = new IdentityHashMap (); (or) Map  hm = new IdentityHashMap (); 

1. IdentidadeHashMap():  Constrói um novo mapa hash de identidade vazio com um tamanho máximo esperado padrão. 

IdentidadeHashMap ele = novo IdentityHashMap ();

2. IdentidadeHashMap (int esperadoMaxSize):  Constrói um novo mapa vazio com o tamanho máximo esperado especificado. 

IdentidadeHashMap ihm = new IdentityHashMap(int esperadoMaxSize);

3. IdentityHashMap (Mapa m):  Constrói um novo mapa hash de identidade contendo os mapeamentos de valores-chave no mapa especificado.

IdentidadeHashMap ihm = new IdentityHashMap(Mapa m);

Operações básicas em IdentityHashMap

1. Adicionando Elementos

Para inserir ou adicionar mapeamento em um IdentityHashMap, temos colocar() e colocarTodos() métodos. put() pode inserir uma chave específica e o valor que ela está mapeando em um mapa específico. Se uma chave existente for passada, o valor anterior será substituído pelo novo valor. putAll() copia todos os elementos, ou seja, os mapeamentos de um mapa para outro. 

Java
   // Java code to illustrate   // adding elements to IdentityHashMap   import     java.util.*  ;   public     class   AddingElementsToIdentityHashMap     {          public     static     void     main  (  String  []     args  )      {      // Creating an empty IdentityHashMap      Map   <  Integer       String  >     identity_hash      =     new     IdentityHashMap   <  Integer       String  >  ();      // Mapping string values to int keys      // using put() method      identity_hash  .  put  (  10       'Geeks'  );      identity_hash  .  put  (  15       '4'  );      identity_hash  .  put  (  20       'Geeks'  );      identity_hash  .  put  (  25       'Welcomes'  );      identity_hash  .  put  (  30       'You'  );      // Displaying the IdentityHashMap      System  .  out  .  println  (  'Initial Mappings are: '      +     identity_hash  );      // Inserting existing key along with new value      // previous value gets returned and stored in      // returned_value      String     returned_value      =     (  String  )  identity_hash  .  put  (  20       'All'  );      // Verifying the returned value      System  .  out  .  println  (  'Returned value is: '      +     returned_value  );      // Displaying the new map      System  .  out  .  println  (  'New map is: '     +     identity_hash  );      // Creating a new Identityhash map and copying      Map   <  Integer       String  >     new_Identityhash_map      =     new     IdentityHashMap   <  Integer       String  >  ();      new_Identityhash_map  .  putAll  (  identity_hash  );      // Displaying the final IdentityHashMap      System  .  out  .  println  (  'The new map: '      +     new_Identityhash_map  );      }   }   

Saída
Initial Mappings are: {30=You 10=Geeks 15=4 25=Welcomes 20=Geeks} Returned value is: Geeks New map is: {30=You 10=Geeks 15=4 25=Welcomes 20=All} The new map: {30=You 10=Geeks 15=4 25=Welcomes 20=All}  

2. Removendo Elementos
Para remover mapeamentos, usamos remover() um método embutido da classe IdentityHashMap e é usado para remover o mapeamento de qualquer chave específica do mapa.

Java
   // Java code to illustrate removing   // elements from IdentityHashMap   import     java.util.*  ;      public     class   RemovingMappingsFromIdentityHashMap     {         public     static     void     main  (  String  []     args  )         {         // Creating an empty IdentityHashMap       Map   <  Integer       String  >     Identity_hash     =     new      IdentityHashMap   <  Integer       String  >  ();             // Mapping string values to int keys       Identity_hash  .  put  (  10       'Geeks'  );         Identity_hash  .  put  (  15       '4'  );         Identity_hash  .  put  (  20       'Geeks'  );         Identity_hash  .  put  (  25       'Welcomes'  );         Identity_hash  .  put  (  30       'You'  );         // Displaying the IdentityHashMap       System  .  out  .  println  (  'Initial Mappings are: '     +         Identity_hash  );         // Removing the existing key mapping       String     returned_value     =         (  String  )  Identity_hash  .  remove  (  20  );         // Verifying the returned value       System  .  out  .  println  (  'Returned value is: '     +         returned_value  );         // Displaying the new map       System  .  out  .  println  (  'New map is: '     +     Identity_hash  );         }      }      

Saída
Initial Mappings are: {30=You 10=Geeks 15=4 25=Welcomes 20=Geeks} Returned value is: Geeks New map is: {30=You 10=Geeks 15=4 25=Welcomes}  

3. Acessando os Elementos

Podemos acessar os elementos de um IdentityHashMap usando o pegar() método, o exemplo disso é dado abaixo.

Java
   // Java code to illustrate the accessing   // elements from IdentityHashMap   import     java.util.*  ;   public     class   AccessingElementsFromIdentityHashMap     {      public     static     void     main  (  String  []     args  )      {      // Creating an empty IdentityHashMap      Map   <  Integer       String  >     identity_hash      =     new     IdentityHashMap   <  Integer       String  >  ();      // Mapping string values to int keys      identity_hash  .  put  (  10       'Geeks'  );      identity_hash  .  put  (  15       '4'  );      identity_hash  .  put  (  20       'Geeks'  );      identity_hash  .  put  (  25       'Welcomes'  );      identity_hash  .  put  (  30       'You'  );      // Displaying the IdentityHashMap      System  .  out  .  println  (  'Initial Mappings are: '      +     identity_hash  );      // Getting the value of 25      System  .  out  .  println  (  'The Value is: '      +     identity_hash  .  get  (  25  ));      // Getting the value of 10      System  .  out  .  println  (  'The Value is: '      +     identity_hash  .  get  (  10  ));          // Using keySet() to get the set view of keys       System  .  out  .  println  (  'The set is: '     +     identity_hash  .  keySet  ());             // Using entrySet() to get the set view       System  .  out  .  println  (  'The set is: '     +         identity_hash  .  entrySet  ());         }   }   

Saída
Initial Mappings are: {30=You 10=Geeks 15=4 25=Welcomes 20=Geeks} The Value is: Welcomes The Value is: Geeks The set is: [30 10 15 25 20] The set is: [30=You 10=Geeks 15=4 25=Welcomes 20=Geeks]  

4. Atravessando
Podemos usar a interface Iterator para percorrer qualquer estrutura do Collection Framework. Como os Iteradores trabalham com um tipo de dados, usamos Entry < ? ? >para resolver os dois tipos separados em um formato compatível. Então, usando o método next(), imprimimos os elementos do IdentityHashMap.

Java
   // Java code to illustrate the    // iterating over IdentityHashmap   import     java.util.*  ;   public     class   IteratingIdentityHashMap     {      public     static     void     main  (  String  []     args  )      {      // Creating an empty IdentityHashMap      IdentityHashMap   <  Integer       String  >     identity_hash      =     new     IdentityHashMap   <  Integer       String  >  ();      // Mapping string values to int keys      identity_hash  .  put  (  10       'Geeks'  );      identity_hash  .  put  (  15       '4'  );      identity_hash  .  put  (  20       'Geeks'  );      identity_hash  .  put  (  25       'Welcomes'  );      identity_hash  .  put  (  30       'You'  );      // Displaying the IdentityHashMap      System  .  out  .  println  (  'Initial Mappings are: '      +     identity_hash  );      // Create an Iterator over the      // IdentityHashMap      Iterator   <  IdentityHashMap  .  Entry   <  Integer       String  >     >      itr     =     identity_hash  .  entrySet  ().  iterator  ();      // The hasNext() method is used to check if there is      // a next element The next() method is used to      // retrieve the next element      while     (  itr  .  hasNext  ())     {      IdentityHashMap  .  Entry   <  Integer       String  >     entry      =     itr  .  next  ();      System  .  out  .  println  (  'Key = '     +     entry  .  getKey  ()      +     ' Value = '      +     entry  .  getValue  ());      }      }   }   

Saída
Initial Mappings are: {30=You 10=Geeks 15=4 25=Welcomes 20=Geeks} Key = 30 Value = You Key = 10 Value = Geeks Key = 15 Value = 4 Key = 25 Value = Welcomes Key = 20 Value = Geeks  

IdentidadeHashMap Sincronizada

Se vários threads acessam um mapa hash de identidade simultaneamente e pelo menos um dos threads modifica o mapa estruturalmente, ele deve ser sincronizado externamente. (Uma modificação estrutural é qualquer operação que adiciona ou exclui um ou mais mapeamentos; apenas alterar o valor associado a uma chave que uma instância já contém não é uma modificação estrutural.) Isso normalmente é realizado por meio da sincronização em algum objeto que encapsula naturalmente o mapa. Se tal objeto não existir, o mapa deverá ser 'embrulhado' usando o Collections.synchronizedMap método. É melhor fazer isso no momento da criação para evitar acesso acidental não sincronizado ao mapa. 

Mapa m = Collections.synchronizedMap(new IdentityHashMap(...));

Métodos de IdentityHashMap

    K – O tipo das chaves no mapa. V – O tipo de valores mapeados no mapa.

MÉTODO

DESCRIÇÃO

claro() Remove todos os mapeamentos deste mapa.
clone() Retorna uma cópia superficial deste mapa hash de identidade: as chaves e os valores em si não são clonados.
contémKey?(chave do objeto) Testa se a referência do objeto especificado é uma chave neste mapa de hash de identidade.
contémValue?(Valor do objeto) Testa se a referência do objeto especificado é um valor neste mapa de hash de identidade.
conjunto de entrada() Retorna um Definir visualização dos mapeamentos contidos neste mapa.
é igual? (Objeto o) Compara o objeto especificado com este mapa quanto à igualdade.
obter?(chave do objeto) Retorna o valor para o qual a chave especificada está mapeada ou nulo se este mapa não contiver nenhum mapeamento para a chave.
código hash() Retorna o valor do código hash para este mapa.
estáVazio() Retornará verdadeiro se este mapa de hash de identidade não contiver mapeamentos de valor-chave.
keySet() Retorna uma visualização de conjunto baseada em identidade das chaves contidas neste mapa.
colocar? (valor V da chave K) Associa o valor especificado à chave especificada neste mapa de hash de identidade.
colocarTudo?(Mapa m) Copia todos os mapeamentos do mapa especificado para este mapa.
remover? (chave do objeto) Remove o mapeamento desta chave deste mapa, se presente.
tamanho() Retorna o número de mapeamentos de valores-chave neste mapa de hash de identidade.
valores() Retorna uma visualização de coleção dos valores contidos neste mapa.

Métodos declarados na classe java.util.AbstractMap

MÉTODO

DESCRIÇÃO

 toString() Retorna uma representação em string deste mapa.

Métodos declarados na interface java.util.Map

MÉTODO

DESCRIÇÃO

 computar?(tecla K BiFunction função de remapeamento) Tenta calcular um mapeamento para a chave especificada e seu valor mapeado atual (ou nulo se não houver mapeamento atual).
computaIfAbsent?(Função da tecla K função de mapeamento) Se a chave especificada ainda não estiver associada a um valor (ou estiver mapeada para nulo), tenta calcular seu valor usando a função de mapeamento fornecida e insere-o neste mapa, a menos que seja nulo.
computaIfPresent?(tecla K BiFunction função de remapeamento) Se o valor da chave especificada estiver presente e tentativas não nulas de calcular um novo mapeamento, dada a chave e seu valor mapeado atual.
forEach?(BiConsumidor Ação) Executa a ação especificada para cada entrada neste mapa até que todas as entradas tenham sido processadas ou a ação gere uma exceção.
getOrDefault?(Chave do objeto V defaultValue) Retorna o valor para o qual a chave especificada é mapeada ou defaultValue se este mapa não contiver nenhum mapeamento para a chave.
mesclar?(chave K valor V BiFunction função de remapeamento) Se a chave especificada ainda não estiver associada a um valor ou estiver associada a null, associa-a ao valor não nulo fornecido.
putIfAbsent?(valor V da chave K) Se a chave especificada ainda não estiver associada a um valor (ou estiver mapeada para nulo), associa-a ao valor fornecido e retorna nulo, caso contrário, retorna o valor atual.
remover?(chave do objeto valor do objeto) Remove a entrada da chave especificada somente se ela estiver atualmente mapeada para o valor especificado.
substituir?(valor V da chave K) Substitui a entrada da chave especificada somente se ela estiver atualmente mapeada para algum valor.
substituir?(tecla K V oldValue V newValue) Substitui a entrada da chave especificada somente se estiver atualmente mapeada para o valor especificado.
substituirTudo?(BiFunção função) Substitui o valor de cada entrada pelo resultado da invocação da função especificada nessa entrada até que todas as entradas tenham sido processadas ou a função gere uma exceção.

IdentidadeHashMap vs.  HashMap

  • IdentityHashMap usa o operador de igualdade '==' para comparar chaves e valores, enquanto HashMap usa o método equals para comparar chaves e valores dentro do Map.
  • Como IdentityHashMap não usa equals(), é comparativamente mais rápido que HashMap para um objeto com equals() caro.
  • IdentityHashMap não exige que as chaves sejam imutáveis, pois não depende de equals().

O programa abaixo ilustra a diferença entre a implementação de IdentityHashMap e HashMap.

Java
   // Java code to demonstrate IdentityHashMap and   // illustration of how it is different from HashMap    import     java.util.Map  ;   import     java.util.HashMap  ;   import     java.util.IdentityHashMap  ;   public     class   IdentityHashMapExample      {      public     static     void     main  (  String  []     args  )         {      // Creating HashMap and IdentityHashMap objects      Map   <  String       String  >     hm     =     new     HashMap   <>  ();      Map   <  String       String  >     ihm     =     new     IdentityHashMap   <>  ();      // Putting key and value in HashMap and IdentityHashMap Object      hm  .  put  (  'hmkey'    'hmvalue'  );      hm  .  put  (  new     String  (  'hmkey'  )  'hmvalue1'  );         ihm  .  put  (  'ihmkey'    'ihmvalue'  );         ihm  .  put  (  new     String  (  'ihmkey'  )  'ihmvalue1'  );             // Print Size of HashMap and WeakHashMap Object      // hm.size() will print 1 since it compares the objects logically      // and both the keys are same      System  .  out  .  println  (  'Size of HashMap is : '  +  hm  .  size  ());          // ihm.size() will print 2 since it compares the objects by reference      System  .  out  .  println  (  'Size of IdentityHashMap is : '  +  ihm  .  size  ());          }   }   

Saída
Size of HashMap is : 1 Size of IdentityHashMap is : 2  


IdentityHashMap é uma classe em Java que implementa a interface Map e usa igualdade de referência para comparar chaves. É semelhante a um HashMap normal, mas usa o operador == para comparar chaves em vez do método equals(). Isso significa que duas chaves com o mesmo conteúdo, mas com referências de objetos diferentes, serão tratadas como chaves distintas em um IdentityHashMap.

Aqui está um exemplo de como usar IdentityHashMap em Java:

 

Java
   import     java.util.IdentityHashMap  ;   public     class   IdentityHashMapExample     {      public     static     void     main  (  String  []     args  )     {      IdentityHashMap   <  String       Integer  >     map     =     new     IdentityHashMap   <>  ();      // Add key-value pairs to the map      String     key1     =     new     String  (  'key'  );      String     key2     =     new     String  (  'key'  );      map  .  put  (  key1       1  );      map  .  put  (  key2       2  );      // Get values from the map using the same and different keys      System  .  out  .  println  (  map  .  get  (  key1  ));     // Output: 1      System  .  out  .  println  (  map  .  get  (  key2  ));     // Output: 2      System  .  out  .  println  (  map  .  get  (  new     String  (  'key'  )));     // Output: null      }   }   

Saída
1 2 null  

Neste exemplo, criamos um IdentityHashMap que mapeia chaves String para valores inteiros. Adicionamos dois pares de valores-chave ao mapa usando dois objetos String diferentes que possuem o mesmo conteúdo. Em seguida, recuperamos valores do mapa usando objetos String iguais e diferentes. Descobrimos que podemos recuperar valores do mapa usando duas chaves diferentes que possuem o mesmo conteúdo, mas não podemos recuperar um valor usando um objeto String que possui o mesmo conteúdo, mas é uma referência de objeto diferente.

Observe que IdentityHashMap tem um comportamento ligeiramente diferente de um HashMap normal e geralmente só é útil em certas situações onde a igualdade de referência é importante. Na maioria dos casos, um HashMap regular é suficiente e mais apropriado.

 

Criar questionário