É possível renomear uma chave Hashmap?

89

Estou procurando uma maneira de renomear uma chave Hashmap, mas não sei se é possível em Java.

Ikes
fonte
11
Puxa, espero que não. Excluir e inserir novamente o par chave / valor parece ser o caminho a seguir. Observe que você normalmente apenas lida com referências no próprio mapa de qualquer maneira.
Maarten Bodewes
4
Não modifique a chave de uma entrada hash! Se você tiver sorte, você mudará para algo com o mesmo hashcode e ficará um pouco louco tentando descobrir o que aconteceu; se você não tiver sorte, acabará com uma entrada que não poderá ser encontrada (bem, não até a próxima reconstrução de toda a tabela). Remover / reinserir é muito mais simples e deve ser bem barato (afinal, são apenas referências).
Donal Fellows

Respostas:

137

Tente remover o elemento e colocá-lo novamente com o novo nome. Supondo que as chaves em seu mapa sejam String, isso poderia ser alcançado desta forma:

Object obj = map.remove("oldKey");
map.put("newKey", obj);
Alexis Pigeon
fonte
59
+1. E mais simples de ler é map.put( "newKey", map.remove( "oldKey" ) );e contémoldKey
Ravinder Reddy
15
No que diz respeito à legibilidade, discordo totalmente, pessoalmente prefiro ver claramente que um objeto é removido do mapa e depois adicionado. E como o OP parece ser muito novo em Java, decidi colocar dessa forma. Por questão de desempenho, entretanto, sua versão é obviamente preferida (já que não acho que o compilador otimizará minha versão do seu jeito).
Alexis Pigeon
3
Para javac 1.8.0_45, a versão de uma linha é dois bytecodes mais curta, o que me surpreendeu. Mais irritante com os genéricos você não pode passar objpara putsem lançar-la ou declará-la como um outro tipo, mas é claro passando o resultado do removetrabalha diretamente.
Samuel Edwin Ward
1
Mas como renomear todas as chaves
gstackoverflow
4
Isso levará a ConcurrentModificationException
gstackoverflow
19

Atribua o valor da chave, que precisa ser renomeada, a uma nova chave. E remova a chave antiga.

hashMap.put("New_Key", hashMap.get("Old_Key"));
hashMap.remove("Old_Key");
Deepak Mani
fonte
19
hashMap.put("New_Key", hashMap.remove("Old_Key"));

Isso fará o que você quiser, mas você notará que a localização da chave mudou.

Mohamed Zakaria El-Zoghbi
fonte
@Vins revisite as documentações: D, remove () retornará o objeto, verifique este tutorialspoint.com/java/util/hashmap_remove.htm
Mohamed Zakaria El-Zoghbi
1
minha má, eu removi meu comentário e votei a favor. Me desculpe por isso.
Vins
9

Você não pode renomear / modificar a chave hashmap depois de adicionada.

A única maneira é excluir / remover a chave e inseri-la com um novo par de chave e valor.

Motivo : Na implementação interna do hashmap, o modificador de chave do Hashmap marcado como final.

static class Entry<K ,V> implements Map.Entry<K ,V>
{
 final K key;
 V value;
 Entry<K ,V> next;
 final int hash;
...//More code goes here
}

Para referência: HashMap

raio de luz
fonte
4

Você não renomeia uma chave hashmap, você tem que inserir uma nova entrada com a nova chave e deletar a antiga.

Hari Menon
fonte
2

Eu diria que a essência das chaves hasmap são para fins de acesso ao índice e nada mais, mas aqui está um hack: fazer uma classe de key-wrapper em torno do valor da chave para que o objeto key-wrapper se torne a chave de hashmap para acesso ao índice, pode acessar e alterar o valor do objeto key-wrapper para suas necessidades específicas:

public class KeyWrapper<T>{

      private T key;
      public KeyWrapper(T key){
         this.key=key;
       }

      public void rename(T newkey){
              this.key=newkey;
       }

}

Exemplo

   HashMap<KeyWrapper,String> hashmap=new HashMap<>();
   KeyWrapper key=new KeyWrapper("cool-key");
   hashmap.put(key,"value");
   key.rename("cool-key-renamed");

Embora você também possa ter uma chave inexistente para obter o valor de uma chave existente do hashmap, temo que isso possa ser criminoso, de qualquer maneira:

public  class KeyWrapper<T>{

        private T key;
        public KeyWrapper(T key){
            this.key=key;
        }

        @Override
        public boolean equals(Object o) {
            return hashCode()==o.hashCode();
        }

        @Override
        public int hashCode() {
            int hash=((String)key).length();//however you want your hash to be computed such that two different objects may share the same at some point
            return hash;
        }
    }

Exemplo

HashMap<KeyWrapper,String> hashmap=new HashMap<>();
KeyWrapper cool_key=new KeyWrapper("cool-key");
KeyWrapper fake_key=new KeyWrapper("fake-key");
hashmap.put(cool_key,"cool-value");
System.out.println("I don't believe it but its: "+hashmap.containsKey(fake_key)+" OMG!!!");
LiNKeR
fonte
1

Veja os pontos abaixo:

1) No,You can not rename the key of hashmap once added.

 2) Very first you have to delete or remove that key and then you can insert with new key with value.

 3) Because in hashmap internal implementation the Hashmap key modifier  is final.
Ghanshyam
fonte
0

Você pode, se em vez de HashMap nativo de Java você usar um Bimap .
Não é a implementação tradicional do Map e você precisa ter certeza de que atende às suas necessidades.

Um bimapa (ou "mapa bidirecional") é um mapa que preserva a exclusividade de seus valores e também de suas chaves. Essa restrição permite que os bimapas suportem uma "visão inversa", que é outro bimapa contendo as mesmas entradas deste bimapa, mas com chaves e valores invertidos.

Usando um bimapa, você pode inverter a visualização e substituir a chave. Verifique o
Apache Commons BidiMap e o Guava BiMap .

dorônia
fonte
0

No meu caso, tinha um mapa contendo chaves não reais -> chaves reais, então tive que substituir as chaves não reais pelas reais em meu mapa (a ideia é como as outras)

getFriendlyFieldsMapping().forEach((friendlyKey, realKey) ->
    if (map.containsKey(friendlyKey))
        map.put(realKey, map.remove(friendlyKey))
);
Basheer AL-MOMANI
fonte