jdfinch3 jdfinch3 - 1 month ago 12
Java Question

Java - Create multiple HashMaps and fill them using a for loop - is there a better way?

To be clear from the start, I have already "solved" this problem (and will post my code at the end). However, my solution seems very hacky and contains a large amount of repetitive code.

My questions are:


  • Is there a better/proper way to do this?

  • Should I use something other than a HashMap?

  • Should I use something other than a for loop?



What I am trying to do:

I need to create between 16 and 20 items (the number varies, but I don't think that matters so I'll just say 20 from now on) and each item has 25 attributes (such as "name", "power", level", etc). Each of the 20 items has the same attributes but with different (random) values.

It seems like a
HashMap
is the obvious way to do this, but I'm open to alternative suggestions. I chose to go with a nested
HashMap
, so I have the outerMap which contains 20 keys and the value of each key is the
HashMap
for 1 item and its 25 attributes. So, to be more precise: I need to create 20
HashMaps
with unique names and each of them with the same 25 keys but with different (random) values.

Again, it seems like a for loop is the obvious way to do this. And, if Java allowed for creating names dynamically (like Item+i for Item1), this would be a simple task. But that's not possible. There are specifically 2 problems I am running in to while trying to do this in a loop.


  1. Naming the 20
    HashMaps
    . If I create the
    HashMaps
    inside a loop there is no way to assign each of them a unique name (such as Item1, Item2, Item3, etc).

  2. When I try to use "put" to store the attribute keys and values I need the current
    HashMap
    name. Basically the same as problem 1, but at a different point in the code.



This is the solution I came up with. The comments in the code should make it clear why I'm doing it this way. Thoughts?

//create outerMap to hold the HashMap for each item
Map<String, Map<String, Object>> itemMap = new LinkedHashMap<>();

//create all possible innerMaps
//manually because you can't name them dynamically in the for loop (example Item+i)
//amount of items unknown, but the range is 16-20
//if less than 20 the remaining HashMaps will simply remain unused
Map<String, Object> Item1 = new LinkedHashMap<>();
Map<String, Object> Item2 = new LinkedHashMap<>();
Map<String, Object> Item3 = new LinkedHashMap<>();
Map<String, Object> Item4 = new LinkedHashMap<>();
Map<String, Object> Item5 = new LinkedHashMap<>();
...through Item20

//for loop that creates and manipulates each of the 25 attributes for each of the 16-20 items
//starting at i = 1 for aesthetic naming purposes
for (i = 1; i < (NumberOfItems + 1); i++)
{
...create and manipulate attribute1
...create and manipulate attribute2
...create and manipulate attribute3
...create and manipulate attribute4
...create and manipulate attribute5
...through attribute25

//you can't call HashMap names dynamically (example Item+i.put(Key, Value)
//so run them through if statements to match i to the correct HashMap
if (i == 1)
{
itemMap.put("Item1", Item1);
Item1.put("attribute1", value);
Item1.put("attribute2", value);
Item1.put("attribute3", value);
...through attribute25

}
else if (i == 2)
{
itemMap.put("Item2", Item2);
Item2.put("attribute1", value);
Item2.put("attribute2", value);
Item2.put("attribute3", value);
...through attribute25
}
else if (i == 3)
{
itemMap.put("Item3", Item3);
Item3.put("attribute1", value);
Item3.put("attribute2", value);
Item3.put("attribute3", value);
...through attribute25
}
...through i == 20
}

Answer

You should use 1 HashMap with the attributes defined as instance variables of a class (who's objects are the values of the HashMap.

ValueObject - Class the holds your attributes.

class ValueObject {
    private String attr1;
    private String attr2;
    ...
    ...
    private String attr25;

    public void setAttr1(String a1){
        attr1 = a1;
    }

    public String getAttr1(){
        return attr1;
    }

    /* Getters and Setters */
    ...
    ...
}

Creating the map - The number of elements added are dynamic.

Map<String, ValueObject> map1 = new LinkedHashMap<>();


for (i = 1; i < (NumberOfItems + 1); i++)
{
    ValueObject vo = new ValueObject();
    vo.setAttr1("a1");
    vo.setAttr2("a2");
    vo.setAttr3("a3");
    ...
    ...
    vo.setAttr25("a25");

    map1.put("item"+i,vo);
}
Comments