Is it possible to create a MAP<> within another MAP<>?

Asked

Viewed 2,716 times

4

It is possible to create a MAP<> within another MAP<>? like this code:

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

If yes:

How I enter values in the second MAP<>?

is a good practice?

I need something like this because both the key of the first MAP<> and the key of the second should not be repeated.

Other ways to implement something like this are welcome

_____**Edit**_____

I need to update data every five minutes

the structure is something like this: //

id1:

     nº do produto1 || dados do produto1

     nº do produto2 || dados do produto2
             .......
     nº do produtoX || dados do produtoX

id2:

     nº do produto1 || dados do produto1

     nº do produto2 || dados do produto2
             .......
     nº do produtoX || dados do produtoX

id3:

     nº do produto1 || dados do produto1

     nº do produto2 || dados do produto2
             .......
     nº do produtoX || dados do produtoX

id’s do not repeat, this is when an equal arrives I have to update the values inside the MAP<>

and the product numbers cannot be repeated either

Basically the values that suffer most updates is the product data.

Possibly this is not the best way to do this, but I confess that I especially like to use MAP because of automatically updated values by the latest and do not let repeat keys

  • 1

    "both the key of the first MAP and the key of the second should not be repeated" You mean, each pair cannot repeat itself, right? Ex.: (a,c) (a,d) (b,c) (b,d) can? And (a, b) (b, a) can? Or even (a, a). If possible, clarify better what your actual problem is, not just your attempt at a solution (i.e. contextualize).

  • According to its edition, it seems to me that a map of maps as you proposed is a good alternative yes. The ids do not repeat in the main map, and the product numbers do not repeat in each sub-map. The product data, these are independent of id to id, right? Ex.: (id1,produto1,dadoX) (id2,produto1,dadoY) So if you need to update the id1, will stay (id1,produto1,dadoZ) (id2,produto1,dadoY) - the other data for the same product do not change. Check?

  • Yes exactly that, the product data is completely related to the product number and the product number is completely related to the id, There is no way these numbers repeat themselves when they repeat it is because the product data has changed so I have to go through and just add a "new data" that as it is a MAP automatically replaces. In your opinion my thinking is correct?

  • 1

    Yes, especially as "the product number is completely related to the id", so there is no conflict. I believe everything is correct then.

3 answers

4

It is possible yes, you entered normally like this:

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 on 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 is a good way to maintain 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 maintain a simpler collection as ArrayList<T>. In your case you cited the need for the two keys to be single, so I believe this is the correct way.

As you quoted in your edit, to edit the content of the sub Map do something like this:

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

I don’t know if this is really what you want, but in a simple way this is how you do it.

4


Yes, it is possible. To access the second Map, simply get a reference for 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 example above showed, tampering with 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 key or another:

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

(Maybe there is some class in Java that serves for this, but if it exists I don’t remember; arrays are not an option, because their equality operation does not take into account the contents of this array - only whether or not it is the same object)

  • But if the method CompareTo for superscript, it is not possible to use an array even? implementing the method as needed by checking the two object keys

  • @Andrade I haven’t worked with Java for years, so I don’t remember: you refer to TreeMap? The HashMap does not use comparators, only function hashCode of your keys. And, if I remember correctly, arrays compare using object identity only. Ex.: int[] a = new int[] { 1, 2 }; int[] b = new int[] { 1, 2 }; In that case, a == b is false, because they’re different objects. Correct me if I’m wrong.

  • Correcting, I meant the method Equals I don’t remember much about Java either because I don’t use it in my day-to-day life, but I remember at my graduation I did an implementation of a List<T> where I overwrote the method Equals and I was able to implement a rule in it that made the comparison based on 4 attributes of the object.

3

Yes, it is possible.

To put a value on the map 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 good practice or not is hard to say depends on what you are looking for 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 I believe this meets.

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".

Browser other questions tagged

You are not signed in. Login or sign up in order to post.