valor - percorrer hashmap java




HashMap para retornar o valor padrão para chaves não encontradas? (9)

Em projetos Java / Kotlin mistos, também considere o Map.withDefault de Kotlin.

É possível ter um HashMap retornando um valor padrão para todas as chaves que não são encontradas no conjunto?


Eu encontrei o LazyMap bastante útil.

Quando o método get (Object) é chamado com uma chave que não existe no mapa, a fábrica é usada para criar o objeto. O objeto criado será adicionado ao mapa usando a chave solicitada.

Isso permite que você faça algo assim:

    Map<String, AtomicInteger> map = LazyMap.lazyMap(new HashMap<>(), ()->new AtomicInteger(0));
    map.get(notExistingKey).incrementAndGet();

A chamada para get cria um valor padrão para a chave dada. Você especifica como criar o valor padrão com o argumento factory para LazyMap.lazyMap(map, factory) . No exemplo acima, o mapa é inicializado para um novo AtomicInteger com valor 0.


Isso é feito por padrão. Retorna null .



O Java 8 introduziu um método padrão computeIfAbsent para a interface Map , que armazena o valor computado computeIfAbsent e, portanto, não quebra o contrato do mapa:

Map<Key, Graph> map = new HashMap<>();
map.computeIfAbsent(aKey, key -> createExpensiveGraph(key));

Origem: http://blog.javabien.net/2014/02/20/loadingcache-in-java-8-without-guava/

Disclamer: Esta resposta não corresponde exatamente ao que o OP pediu, mas pode ser útil em alguns casos, combinando o título da pergunta quando o número de chaves é limitado e o armazenamento em cache de diferentes valores seria lucrativo. Ele não deve ser usado em caso contrário com muitas teclas e o mesmo valor padrão que isso desnecessariamente desperdiçaria memória.


Usar:

myHashMap.getOrDefault(key, defaultValue);

Você não pode simplesmente criar um método estático que faz exatamente isso?

private static <K, V> V getOrDefault(Map<K,V> map, K key, V defaultValue) {
    return map.containsKey(key) ? map.get(key) : defaultValue;
}

Você pode simplesmente criar uma nova classe que herda HashMap e adicione o método getDefault. Aqui está um código de exemplo:

public class DefaultHashMap<K,V> extends HashMap<K,V> {
    public V getDefault(K key, V defaultValue) {
        if (containsKey(key)) {
            return get(key);
        }

        return defaultValue;
    }
}

Eu acho que você não deve sobrescrever o método (chave K) em sua implementação, por causa das razões especificadas por Ed Staub em seu comentário e porque você vai quebrar o contract da interface do Mapa (isso pode levar a alguns difíceis de encontrar) insetos).


/**
 * Extension of TreeMap to provide default value getter/creator.
 * 
 * NOTE: This class performs no null key or value checking.
 * 
 * @author N David Brown
 *
 * @param <K>   Key type
 * @param <V>   Value type
 */
public abstract class Hash<K, V> extends TreeMap<K, V> {

    private static final long serialVersionUID = 1905150272531272505L;

    /**
     * Same as {@link #get(Object)} but first stores result of
     * {@link #create(Object)} under given key if key doesn't exist.
     * 
     * @param k
     * @return
     */
    public V getOrCreate(final K k) {
        V v = get(k);
        if (v == null) {
            v = create(k);
            put(k, v);
        }
        return v;
    }

    /**
     * Same as {@link #get(Object)} but returns specified default value
     * if key doesn't exist. Note that default value isn't automatically
     * stored under the given key.
     * 
     * @param k
     * @param _default
     * @return
     */
    public V getDefault(final K k, final V _default) {
        V v = get(k);
        return v == null ? _default : v;
    }

    /**
     * Creates a default value for the specified key.
     * 
     * @param k
     * @return
     */
    abstract protected V create(final K k);
}

Exemplo de uso:

protected class HashList extends Hash<String, ArrayList<String>> {
    private static final long serialVersionUID = 6658900478219817746L;

    @Override
        public ArrayList<Short> create(Short key) {
            return new ArrayList<Short>();
        }
}

final HashList haystack = new HashList();
final String needle = "hide and";
haystack.getOrCreate(needle).add("seek")
System.out.println(haystack.get(needle).get(0));




hashmap