JavaRush /Blogue Java /Random-PT /9 principais perguntas sobre mapas em Java
Treefeed
Nível 21

9 principais perguntas sobre mapas em Java

Publicado no grupo Random-PT
Lembre-se de que um Mapa são dados estruturados que consistem em um conjunto de pares de valores-chave, e cada chave só pode ser usada uma vez em um único Mapa. Este tópico aborda 9 questões básicas sobre o uso do Map em Java e suas classes implementadas. Para simplificar, usarei generalizações nos exemplos . Portanto, escreverei simplesmente Map, sem especificar o especificador Map. Mas você pode assumir que ambos os valores de K e V são comparáveis, o que significa que K estende Comparable e V também estende Comparable .9 principais perguntas sobre mapas em Java - 1

0. Convertendo um mapa em uma lista

Em Java, a interface Map oferece três tipos de coleções: um conjunto de chaves, um conjunto de valores e um conjunto de valores-chave. Todos eles podem ser transformados em uma Lista usando o construtor ou método addAll(). O trecho de código a seguir demonstra como criar um ArrayList a partir de um mapa.
// list of keys
List keyList = new ArrayList(Map.keySet());
//list of values
List valueList = new ArrayList(Map.valueSet());
//list key-value
List entryList = new ArrayList(Map.entrySet());

1. Percorra todos os valores do mapa

Percorrer cada par de valores-chave é o procedimento mais básico para percorrer um mapa. Em Java, cada par é armazenado em um campo Map chamado Map.Entry . Map.entrySet()retorna um conjunto de valores-chave, então a maneira mais eficiente de iterar todos os valores de um Mapa seria:
for(Entry entry: Map.entrySet()) {
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}
Também podemos usar Iterator, especialmente em versões anteriores ao JDK 1.5
Iterator itr = Map.entrySet().iterator();
while(itr.hasNext()) {
  Entry entry = itr.next();
  //get the key
  K key = entry.getKey();
  //get value
  V value = entry.getValue();
}

2. Ordenação do mapa por chaves

Organizar mapas por chaves é outro procedimento comumente utilizado. A primeira maneira é adicionar Map.Entry à lista e classificar usando um comparador que classifica por valores.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getKey().compareTo(e2.getKey());
  }
});
Outra forma: use SortedMap , que, além disso, também organiza suas chaves em ordem. Porém, todas as chaves devem incorporar Comparável ou ser aceitas pelo comparador. Uma das classes implementadas SortedMapé TreeMap . Seu construtor aceita um comparador. O código a seguir mostra como transformar um normal Mapem um ordenado.
SortedMap sortedMap = new TreeMap(new Comparator() {

  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }

});
sortedMap.putAll(Map);

3. Ordenar mapa por valores

Adicionar um mapa à lista e depois classificá-lo funciona neste caso, mas desta vez você precisa usar Entry.getValue(). O código abaixo é quase o mesmo de antes.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getValue().compareTo(e2.getValue());
  }

});
Ainda podemos usá-lo SortedMapneste caso, mas apenas se os valores forem únicos. Nesse caso, você pode transformar o par de valores-chave em um valor-chave. Esta solução tem limitações severas e não é recomendada por mim.

4. Inicializando um mapa estático/imutável

Quando você deseja que um Mapa permaneça imutável, uma boa maneira é copiá-lo para um Mapa imutável. Esta técnica de programação defensiva o ajudará a criar um mapa que não seja apenas seguro de usar, mas também seguro para threads. Para inicializar um mapa estático/imutável, podemos usar um inicializador static(veja abaixo). O problema desse código é que apesar de declarar um Map como static final, ainda podemos trabalhar com ele após a inicialização, por exemplo Test.Map.put(3,"three");. Portanto, não é uma imutabilidade real. Para criar um mapa imutável usando um inicializador estático, precisamos de uma classe superanônima, que adicionaremos ao mapa imutável na última etapa de inicialização. Por favor, olhe a segunda parte do código. Quando uma UnsupportedOperationException será lançada se você executar o Test.Map.put(3,"three");.
public class Test {

  private static final Map Map;
  static {
    Map = new HashMap();
    Map.put(1, "one");
    Map.put(2, "two");
  }
}
public class Test {

  private static final Map Map;
  static {
    Map aMap = new HashMap();
    aMap.put(1, "one");
    aMap.put(2, "two");
    Map = Collections.unmodifiableMap(aMap);
  }
}
A biblioteca Guava também oferece suporte a várias maneiras de inicializar coleções estáticas e imutáveis. Para saber mais sobre os benefícios do utilitário de coleções imutáveis ​​do Guava, consulte a seção Coleções imutáveis ​​no Guia do Guava .

5. Diferença entre HashMap, TreeMap e Hashtable

Existem três implementações principais da interface Map em Java: HashMap , TreeMap e Hashtable . As principais diferenças são as seguintes:
  • Ordem de passagem . HashMap e HashTable não garantem a ordem do Mapa; em particular, não garantem que a ordem permanecerá a mesma ao longo do tempo. Mas TreeMapirá ordenar todos os valores na “ordem natural” das chaves ou por um comparador.
  • Pares de valores-chave válidos. HashMappermite que você tenha uma chave nula e um valor nulo. HashTablenão permite uma chave nula ou um valor nulo. Se TreeMapa ordem natural for usada ou o comparador não permitir uma chave nula, uma exceção será lançada.
  • Sincronização . Apenas HashTablesincronizado, o resto não. Mas, "se uma implementação thread-safe não for necessária, é recomendado usar " HashMapem vez disso HashTable.
Comparação mais detalhada
.                       | HashMap | HashTable | TreeMap
-------------------------------------------------------

Упорядочивание          |нет      |нет        | да
null в ключ-meaning    | да-да   | нет-нет   | нет-да
синхронизировано        | нет     | да        | нет
производительность      | O(1)    | O(1)      | O(log n)
воплощение              | корзины | корзины   | красно-чёрное дерево
Leia mais sobre o relacionamento HashMap vs. TreeMap vs. Tabela hash vs. LinkedHashMap .

6. Mapa com pesquisa/visualização reversa

Às vezes, precisamos de um conjunto de pares chave-chave, o que significa que os valores são tão exclusivos quanto as chaves (um padrão um para um). Esta consistência permite criar uma "visão/pesquisa invertida" no Mapa. Ou seja, podemos encontrar uma chave pelo seu valor. Essa estrutura de dados é chamada de Map bidirecional , que infelizmente não é suportada pelo JDK. Tanto o Apache Common Collections quanto o Guava oferecem implementações de mapas bidirecionais chamadas BidiMap e BiMap, respectivamente. Ambos introduzem uma restrição que impõe um mapeamento 1:1 entre chaves e valores.

7. Cópia superficial do mapa

Quase todos, senão todos, Mapas em Java contêm um construtor de cópia para outro Mapa. Mas o procedimento de cópia não está sincronizado. O que significa que quando um thread copia um mapa, outro thread pode alterar sua estrutura. Para evitar a dessincronização repentina da cópia, um deles deve ser usado nesse caso Collections.synchronizedMap().
Map copiedMap = Collections.synchronizedMap(Map);
Outra maneira interessante de copiar superficialmente é usar o arquivo clone(). Mas NÃO é recomendado nem mesmo pelo criador do framework de coleções Java, Joshua Bloch. No debate " Construtor de cópia vs. clonagem ", ele assume a posição: Citação: "Muitas vezes incluo um método de clone público em classes concretas porque as pessoas esperam que eles estejam lá. ... é uma pena que a clonagem esteja quebrada, mas é aconteceu... A clonagem é um ponto fraco e acho que as pessoas deveriam ser alertadas sobre suas limitações." Por esse motivo, nem mostro como usar o método clone()para copiar Map

8. Crie um mapa vazio

Se Mapimutável, use:
Map = Collections.emptyMap();
Ou use qualquer outra modalidade. Por exemplo:
Map = new HashMap();
FIM
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION