Implementações de mapas imutáveis ​​em Java

Implementações de mapas imutáveis ​​em Java

1. Visão geral

Às vezes, é preferível não permitir modificações emjava.util.Map , como compartilhar dados somente leitura entre threads. Para esse fim, podemos usar um Mapa Não Modificável ou um Mapa Imutável.

Neste tutorial rápido, veremos qual é a diferença entre eles. Em seguida, apresentaremos várias maneiras pelas quais podemos criar um Mapa Imutável.

2. Immodificável vs Imutável

Um mapa não modificável é apenas um invólucro sobre um mapa modificável e não permite modificações nele diretamente:

Map mutableMap = new HashMap<>();
mutableMap.put("USA", "North America");

Map unmodifiableMap = Collections.unmodifiableMap(mutableMap);
assertThrows(UnsupportedOperationException.class,
  () -> unmodifiableMap.put("Canada", "North America"));

Mas o mapa mutável subjacente ainda pode ser alterado e as modificações são refletidas no mapa Unmodifiable:

mutableMap.remove("USA");
assertFalse(unmodifiableMap.containsKey("USA"));

mutableMap.put("Mexico", "North America");
assertTrue(unmodifiableMap.containsKey("Mexico"));

An Immutable Map, on the other hand, contains its own private data and doesn’t allow modifications to it. Portanto, os dados não podem mudar de forma alguma uma vez que uma instância do Mapa Imutável é criada.

3. Mapa Imutável da Goiaba

Guava fornece versões imutáveis ​​de cadajava.util.Map usingImmutableMap. Ele lança umUnsupportedOperationException sempre que tentamos modificá-lo.

Uma vez que contém seus próprios dados privados, esses dados não serão alterados quando o mapa original for alterado.

Agora vamos discutir várias maneiras de criar instâncias deImmutableMap.

3.1. Usando o métodocopyOf()

Primeiro, vamos usar o métodoImmutableMap.copyOf() que retorna uma cópia de todas as entradas como no mapa original:

ImmutableMap immutableMap = ImmutableMap.copyOf(mutableMap);
assertTrue(immutableMap.containsKey("USA"));

Não pode ser modificado direta ou indiretamente:

assertThrows(UnsupportedOperationException.class,
  () -> immutableMap.put("Canada", "North America"));

mutableMap.remove("USA");
assertTrue(immutableMap.containsKey("USA"));

mutableMap.put("Mexico", "North America");
assertFalse(immutableMap.containsKey("Mexico"));

3.2. Usando o métodobuilder()

Também podemos usar o métodoImmutableMap.builder() para criar uma cópia de todas as entradas como no mapa original.

Além disso, podemos usar este método para adicionar entradas adicionais que não estão presentes no mapa original:

ImmutableMap immutableMap = ImmutableMap.builder()
  .putAll(mutableMap)
  .put("Costa Rica", "North America")
  .build();
assertTrue(immutableMap.containsKey("USA"));
assertTrue(immutableMap.containsKey("Costa Rica"));

Da mesma forma que no exemplo anterior, não podemos modificá-lo direta ou indiretamente:

assertThrows(UnsupportedOperationException.class,
  () -> immutableMap.put("Canada", "North America"));

mutableMap.remove("USA");
assertTrue(immutableMap.containsKey("USA"));

mutableMap.put("Mexico", "North America");
assertFalse(immutableMap.containsKey("Mexico"));

3.3. Usando o métodoof()

Finalmente, podemos usar o métodoImmutableMap.of() para criar um mapa imutável com um conjunto de entradas fornecidas instantaneamente. Ele suporta no máximo cinco pares de chave / valor:

ImmutableMap immutableMap
  = ImmutableMap.of("USA", "North America", "Costa Rica", "North America");
assertTrue(immutableMap.containsKey("USA"));
assertTrue(immutableMap.containsKey("Costa Rica"));

Também não podemos modificá-lo:

assertThrows(UnsupportedOperationException.class,
  () -> immutableMap.put("Canada", "North America"));

4. Conclusão

Neste artigo rápido, discutimos as diferenças entre um mapa não modificável e um mapa imutável.

Também demos uma olhada em diferentes maneiras de criarImmutableMap. de Guava

E, como sempre, os exemplos de código completos estão disponíveisover on GitHub.