Is it possible to create a MAP within another MAP?

4

Is it possible to create a MAP<> within another MAP<> ? type this code:

private Map<String, Map<String,Object>>  mapTESTE = new HashMap<String, Map<String,Object>>();

If yes:

How do I insert values into the second MAP < >?

Is it a good practice?

I need something like this because both the key of the first MAP

asked by anonymous 28.07.2014 / 15:32

3 answers

4

Yes, it is possible. To access the second Map , simply get a reference to it (using the first key):

Map<String,Object> interno = new HashMap<String,Object>()
mapTESTE.put(primeiraChave, interno);
interno.put(segundaChave, object);

...

// Obtém o valor
Object object = mapTESTE.get(primeiraChave).get(segundaChave);

// Atualiza o valor
mapTESTE.get(primeiraChave).put(segundaChave, novoValor);

// Atualiza a segunda chave
Object valor = mapTESTE.get(primeiraChave).remove(segundaChave);
mapTESTE.get(primeiraChave).put(novaChave, valor);

// Atualiza a primeira chave (para todos os valores da segunda)
Map<String,Object> interno = mapTESTE.remove(primeiraChave);
mapTESTE.put(novaChave, interno);

Whether or not this is the best option depends on whether or not there is a hierarchy between the keys. As the above example showed, tinkering in the first key affects all values independent of the second key. Sometimes this is exactly what you want, but in other situations it may not be.

If the keys are independent, then it is preferable to create an object composing the two keys:

class Chaves {
    String primeira;
    String segunda;
    // Implementar equals e hashCode (importante)
}

And use this object as your map key:

Map<Chaves,Object> mapTESTE

You can even create auxiliary maps to search for one or another key:

Map<String,Chaves> buscaPorPrimeiraChave;
Map<String,Chaves> buscaPorSegundaChave;

(Maybe there is some class in Java that works for this, but if it exists I do not remember: arrays are not an option, since their equality operation does not take into account the contents of that array - only if it is the same object )

    
28.07.2014 / 15:46
4

It is possible to do so,

Map<String, Map<String,Object>> mapTESTE = new HashMap<String, Map<String,Object>>();
Map<String, Object> segundoMap = new HashMap<String, Object>();
segundoMap.put("key1.1", "value1.1");
mapTESTE.put("key1", segundoMap);

Or so in a loop :

Map<String, Map<String,Object>> mapTESTE = new HashMap<String, Map<String,Object>>();
int size1 = 3;
int size2 = 5;
for (int i = 0; i < size1; i++) {
    Map<String, Object> segundoMap = new HashMap<String, Object>();
    for (int j = 0; j < size2; j++) {
        // key nesse formato: key-i-j, onde 'i' é o indice do primeiro map e 'j' é o indice do segundo map
        segundoMap.put("key-" + i + " - "+ j, "value-" + i + " - "+ j);
    }
    // key nesse formato: key-i, onde 'i' é o indice do primeiro map
    mapTESTE.put("key-" + i, segundoMap);
}

If it's a good practice?

Yes it is a good way to keep collections with unique keys, it should only be analyzed if there is a need to maintain a collection in this structure or it is possible to keep a collection as simple as ArrayList<T> . In your case you mentioned the need for both keys to be unique, so I believe this is the correct way.

As you mentioned in your edition, to edit the contents of the sub Map do something like this:

mapTESTE.get("key1").put("key1.1", "novo valor");
  

I do not know if this is what you want, but that's the way it's done.

    
28.07.2014 / 15:38
3

Yes, it is possible.

To put a value on the map that is inside the first map, do so:

Map<String, Map<String, String>> teste = new HashMap<String, Map<String, String>>();
teste.put("primeiro", new HashMap<String, String>());
teste.get("primeiro").put("primeiro chave do sub map", "primeiro valor do sub map");

Whether this is a good practice or not difficult to say depends on what you are looking for, it may be a good solution. An alternative would be to create a class that contains two attributes to be used as the value of your first map.

class MeuMapa {
    private Set<String> primeiro;
    private String segundo;
    public MeuMapa(Set<String> primeiro, String segundo) {
        this.primeiro = primeiro;
        this.segundo = segundo;
    }
    public Set<String> getPrimeiro() { return primeiro; }
    public void setPrimeiro(Set<String> primeiro) { this.primeiro = primeiro; }
    public String getSegundo() { return segundo; }
    public void setSegundo(String segundo) { this.segundo = segundo; }
    //implemente o hashCode() e o equals() aqui
    //o próprio eclipse faz isso de forma automática
}

Note that the first attribute is a Set, which does not allow duplicates, so as you said that neither the first value of your map nor the first value of your second map can be repeated,

To use it would look like this:

Map<String, MeuMapa> mapa = new HashMap<>();
MeuMapa meuMapa = new MeuMapa(new HashSet<String>(), "segundo");
mapa.put("primeiro", meuMapa);      

But it all depends on what your need is, you can go one way or the other, both can be considered "right."

    
28.07.2014 / 15:42