Um guia para o EnumMap

Um guia para o EnumMap

1. Visão geral

EnumMap é uma simplificaçãoMap que leva exclusivamenteEnum como suas chaves.

Neste tutorial, discutiremos suas propriedades, casos de uso comuns e quando devemos usá-lo.

2. Configuração do Projeto

Imagine um requisito simples em que precisamos mapear os dias da semana com o esporte que praticamos naquele dia:

Monday     Soccer
Tuesday    Basketball
Wednesday  Hiking
Thursday   Karate

Para isso, poderíamos usar um enum:

public enum DayOfWeek {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

O que veremos em breve será a chave do nosso mapa.

3. Criação

Para começar a explorarEnumMap, primeiro precisamos instanciar um:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");

E aqui está nossa primeira diferença para algo mais comum, comoHashMap. Observe que comHashMap, a parametrização do tipo é suficiente, o que significa que podemos escapar comnew HashMap<>(). However, EnumMap requires the key type in the constructor.

3.1. EnumMap Copy Construtor

EnumMap também é fornecido com dois construtores de cópia. O primeiro leva outroEnumMap:

EnumMap activityMap = new EnumMap<>(DayOfWeek.class);
activityMap.put(DayOfWeek.MONDAY, "Soccer");
activityMap.put(DayOfWeek.TUESDAY, "Basketball");

EnumMap activityMapCopy = new EnumMap<>(dayMap);
assertThat(activityMapCopy.size()).isEqualTo(2);
assertThat(activityMapCopy.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMapCopy.get(DayOfWeek.TUESDAY)).isEqualTo("Basketball");

3.2. Map Copy Construtor

Ou,if we have a non-empty Map whose key is an enum, then we can do that, too:

Map ordinaryMap = new HashMap();
ordinaryMap.put(DayOfWeek.MONDAY, "Soccer");

EnumMap enumMap = new EnumMap(ordinaryMap);
assertThat(enumMap.size()).isEqualTo(1);
assertThat(enumMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

Observe que o mapa não deve estar vazio para queEnumMap can determine o tipo de chave de uma entrada existente.

Se o mapa especificado contiver mais de um tipo de enum, o construtor lançaráClassCastException.

4. Adicionando e Recuperando Elementos

Depois de instanciar umEnumMap, podemos adicionar nosso esporte usando o métodoput():

activityMap.put(DayOfWeek.MONDAY, "Soccer");

E para recuperá-lo, podemos usarget():

assertThat(clubMap.get(DayOfWeek.MONDAY)).isEqualTo("Soccer");

5. Verificando os Elementos

Para verificar se temos um mapeamento definido para um determinado dia, usamoscontainsKey():

activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isTrue();

E, para verificar se um determinado esporte está mapeado para qualquer tecla, usamoscontainsValue():

assertThat(activityMap.containsValue("Hiking")).isTrue();

5.1. null como valor

Agora,null é um valor semanticamente válido paraEnumMap.

Vamos associarnull a “não fazer nada” e mapeá-lo para sábado:

assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isFalse();
assertThat(activityMap.containsValue(null)).isFalse();
activityMap.put(DayOfWeek.SATURDAY, null);
assertThat(activityMap.containsKey(DayOfWeek.SATURDAY)).isTrue();
assertThat(activityMap.containsValue(null)).isTrue();

6. Removendo elementos

Para cancelar o mapeamento de um dia específico, simplesmenteremove():

activityMap.put(DayOfWeek.MONDAY, "Soccer");
assertThat(activityMap.remove(DayOfWeek.MONDAY)).isEqualTo("Soccer");
assertThat(activityMap.containsKey(DayOfWeek.MONDAY)).isFalse();

Como podemos observar,remove(key) retorna o valor anterior associado à chave, ounull  se não houver mapeamento para a chave.

Também podemos escolherunmap a particular day only if that day is mapped to a particular activity:

activityMap.put(DayOfWeek.Monday, "Soccer");
assertThat(activityMap.remove(DayOfWeek.Monday, "Hiking")).isEqualTo(false);
assertThat(activityMap.remove(DayOfWeek.Monday, "Soccer")).isEqualTo(true);

remove(key, value) remove a entrada para a chave especificada apenas se a chave estiver mapeada para o valor especificado.

7. Vistas da coleção

Assim como com mapas comuns, com qualquerEnumMap, podemos ter 3 visualizações ou sub-coleções diferentes.

Primeiro, vamos criar um novo mapa de nossas atividades:

EnumMap activityMap = new EnumMap(DayOfWeek.class);
activityMap.put(DayOfWeek.THURSDAY, "Karate");
activityMap.put(DayOfWeek.WEDNESDAY, "Hiking");
activityMap.put(DayOfWeek.MONDAY, "Soccer");

7.1. values

A primeira visualização do nosso mapa de atividades évalues() que, como o nome sugere, retorna todos os valores no mapa:

Collection values = dayMap.values();
assertThat(values)
  .containsExactly("Soccer", "Hiking", "Karate");

Observe aqui queEnumMap  é um mapa ordenado. Ele usa a ordem doDayOfWeek enum para determinar a ordem das entradas.

7.2. keySet

Da mesma forma,keySet() retorna uma coleção de chaves, novamente na ordem enum:

Set keys = dayMap.keySet();
assertThat(keys)
        .containsExactly(DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY, DayOfWeek.SATURDAY);

7.3. entrySet

Por último,entrySet() retorna o mapeamento em pares de chave e valor:

assertThat(dayMap.entrySet())
    .containsExactly(
        new SimpleEntry(DayOfWeek.MONDAY, "Soccer"),
        new SimpleEntry(DayOfWeek.WEDNESDAY, "Hiking"),
        new SimpleEntry(DayOfWeek.THURSDAY, "Karate")
    );

A ordenação de um mapa pode certamente ser útil, e iremos em mais detalhes em nosso tutorial quecompares TreeMap to HashMap.

7.4. Mutabilidade

Agora, lembre-se de que quaisquer alterações que fizermos no mapa de atividades original serão refletidas em qualquer uma de suas visualizações:

activityMap.put(DayOfWeek.TUESDAY, "Basketball");
assertThat(values)
    .containsExactly("Soccer", "Basketball", "Hiking", "Karate");

E vice versa; quaisquer alterações que fizermos nas sub-visualizações serão refletidas no mapa de atividades original:

values.remove("Hiking");
assertThat(activityMap.containsKey(DayOfWeek.WEDNESDAY)).isFalse();
assertThat(activityMap.size()).isEqualTo(3);

Por contrato deEnumMap comMap interface, as subvisualizações são apoiadas pelo mapa original.

8. Quando usarEnumMap

8.1. atuação

UsarEnum como chave torna possível fazer alguma otimização de desempenho extra,like a quicker hash computation since all possible keys are known in advance.

A simplicidade de terenum como chave significa queEnumMap precisa apenas de backup por um JavaArray antigo simples com uma lógica muito simples para armazenamento e recuperação. Por outro lado, simplificaçõesMap genéricas precisam atender a preocupações relacionadas a ter um objeto genérico como sua chave. Por exemplo,HashMap https: //www.example.com/java-hashmap [precisa de uma estrutura de dados complexa e uma lógica de armazenamento e recuperação consideravelmente mais complexa] para atender à possibilidade de colisão de hash.

8.2. Funcionalidade

Além disso, como vimos,EnumMap  é um mapa ordenado, em que suas visualizações irão iterar em ordem enum. Para obter um comportamento semelhante para cenários mais complexos, podemos olhar paraTreeMap ouLinkedHashMap.

9. Conclusão

Neste artigo, exploramos a implementaçãoEnumMap da interfaceMap. Ao trabalhar comEnum as uma chave, a varreduraEnumMap é útil.

O código-fonte completo para todos os exemplos usados ​​neste tutorial pode ser encontrado emGitHub project.