É possível HashMap
retornar um valor padrão para todas as chaves que não foram encontradas no conjunto?
java
dictionary
hashmap
Larry
fonte
fonte
getOrDefault()
link daRespostas:
[Atualizar]
Conforme observado por outras respostas e comentadores, no Java 8 você pode simplesmente ligar
Map#getOrDefault(...)
.[Original]
Não há implementação de mapa que faça isso exatamente, mas seria trivial implementar o seu próprio, estendendo o HashMap:
fonte
(v == null)
para(v == null && !this.containsKey(k))
, caso eles tenham adicionado umnull
valor propositalmente . Eu sei, este é apenas um caso de esquina, mas o autor pode se deparar com isso.!this.containsValue(null)
. Isso é sutilmente diferente de!this.containsKey(k)
. AcontainsValue
solução falhará se alguma outra chave tiver sido atribuída explicitamente ao valornull
. Por exemplo:map = new HashMap(); map.put(k1, null); V v = map.get(k2);
Nesse caso,v
ainda estaránull
correto?No Java 8, use Map.getOrDefault . Ele pega a chave e o valor a retornar se nenhuma chave correspondente for encontrada.
fonte
getOrDefault
é muito bom, mas requer a definição padrão sempre que o mapa é acessado. Definir um valor padrão uma vez também traria benefícios de legibilidade ao criar um mapa estático de valores.private static String get(Map map, String s) { return map.getOrDefault(s, "Error"); }
Use o DefaultedMap do Commons se não quiser reinventar a roda, por exemplo,
Você também pode passar um mapa existente se não estiver encarregado de criar o mapa em primeiro lugar.
fonte
O Java 8 introduziu um bom método padrão computeIfAbsent para fazer a
Map
interface, que armazena valor lento e, portanto, não quebra o contrato do mapa:Origem: http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/
Disclamer: Essa resposta não corresponde exatamente ao que o OP pediu, mas pode ser útil em alguns casos, corresponder ao título da pergunta quando o número de chaves for limitado e o armazenamento em cache de valores diferentes for rentável. Não deve ser usado no caso oposto, com muitas chaves e o mesmo valor padrão, pois isso desperdiçaria desnecessariamente memória.
fonte
Você não pode simplesmente criar um método estático que faça exatamente isso?
fonte
Você pode simplesmente criar uma nova classe que herda HashMap e adicione o método getDefault. Aqui está um código de exemplo:
Eu acho que você não deve substituir o método get (chave K) em sua implementação, por causa dos motivos especificados por Ed Staub em seu comentário e porque você quebrará o contrato da interface do Mapa (isso pode potencialmente levar a alguns difíceis de encontrar) insetos).
fonte
get
método. Por outro lado - sua solução não permite o uso da classe via interface, o que geralmente pode ser o caso.Usar:
fonte
Faz isso por padrão. Retorna
null
.fonte
HashMap
apenas para esta funcionalidade quandonull
está perfeitamente bem.NullObject
padrão, ou não quiser espalhar verificações nulas por todo o código - um desejo que eu entendo completamente.Em java 8+
fonte
Achei o LazyMap bastante útil.
Isso permite que você faça algo assim:
A chamada para
get
cria um valor padrão para a chave fornecida. Você especifica como criar o valor padrão com o argumento de fábrica paraLazyMap.lazyMap(map, factory)
. No exemplo acima, o mapa é inicializado para um novoAtomicInteger
com o valor 0.fonte
List<String>
- usando a resposta aceita, eu correria o risco de usar a mesma lista para cada nova chave, em vez de (digamos) anew ArrayList<String>()
de uma fábrica.Não diretamente, mas você pode estender a classe para modificar seu método get. Aqui está um exemplo pronto para usar: http://www.java2s.com/Code/Java/Collections-Data-Structure/ExtendedVersionofjavautilHashMapthat fornece um método de extensão de método avançado para aceleração de valor de falha.htm
fonte
Exemplo de uso:
fonte
Eu precisava ler os resultados retornados de um servidor em JSON onde não podia garantir que os campos estivessem presentes. Estou usando a classe org.json.simple.JSONObject, que é derivada do HashMap. Aqui estão algumas funções auxiliares que eu empreguei:
fonte
Em projetos Java / Kotlin mistos, considere também o Map.withDefault do Kotlin .
fonte