2

I am working on a videogame with a friend. To account for different types of items, we originally had a class for each item extending an Item class. There wasn't much data in these classes, so I was looking for an alternative so that our workspace wasn't so cluttered. I started learning about HashMaps, and I thought they were an awesome way to add items. We could also set it up so that instead of accessing the items in the HashMap with an int, which would basically just make it an ArrayList, we could access them with Strings. So I started adding this functionality, creating anonymous Items in the Item class,

    private static Item coal = new Item() {
        weight = .2;
        setImageID(0, 16);
    }

and adding them to the HashMap.

    itemMap.put("Coal", coal);

After doing a few of these, I realized that there was only one item of each type in the list, and if we ever wanted to have multiples of those items that could be modified without modifying the original, we would need to make copies. I started doing research on how to do that. We could use a copy constructor, but there are too many variables in an Item for that to be done efficiently. We certainly could do that, but I was wondering if there was a simple solution. Could we make all of the items final? I'm just spitballing, because I am totally new to this area of programming. We could be doing this whole thing wrong, too. I just need a way to use a HashMap to create something of an "Item database" that I can use to access an indefinite amount of an item in the list. Any suggestions?

jchitel
  • 2,999
  • 4
  • 36
  • 49

4 Answers4

5

How about having a HashMap that has a value of a set (or a list depending on if the same item can exist more than once)?

Map<String, Set<Item>> map = new HashMap<String, Set<Item>>();

That way, you can have multiple items for each type.

One idiom for adding a new item to the type's set is below:

Set<Item> items = map.get(type);
if (items == null) {
     items = new HashSet<Item>();
     items.put(type, items); 
}
items.add(item);

It might not even be a bad idea to use an Enum for your type instead of just a String. Then you could do something like map.put(Item.COAL, itemSet); This would help guard against typos and case sensitivity issues.

AHungerArtist
  • 9,332
  • 17
  • 73
  • 109
0

Would a Hashmap<string,ArrayList<Item>> perhaps work? then instead of itemMap.put("Coal", coal), you'd have to make sure that itemMap.get("Coal") already has an array list, and append the new item to the list.

Alexander Corwin
  • 1,097
  • 6
  • 11
0

Did you know you could specify your map with statements like these:

HashMap<Integer, Item[]> map = new HashMap<Integer, Item[]>();

or

HashMap<String, Item[]> map = new HashMap<String, Item[]>();

Associating each set/array/list of items with an integer or string could work for your problem.

Juvanis
  • 25,802
  • 5
  • 69
  • 87
0

If I'm understanding this correctly, you should have a list of all the items inside each of the HashMap to access multiple items under an item type. To do this just make a HashMap<String, ArrayList<Item>>. When you first create an item type, create a new ArrayList<Item> and on adding subsequent items of the same item type, just append to the list.

However, HashMap isn't quite that efficient for this. If you have a known quantity of item types, I would make it an ArrayList<ArrayList<Item>> such that you initialize the outer ArrayList with an initialCapacity equal to the number of item types you have and have a method that converts the name of the item type to the index that it is stored in the outer ArrayList to be more memory efficient due to lack of load factor and bypasses the overhead of the hashing function. An alternative to the method that converts name of item to index is to maybe add an item type id to each item type.

So you would have:

class Coal {
    public int id = 0
}

Assuming your outer ArrayList is named itemTypes and your item is coal, adding would simply be:

itemTypes.get(coal.id).add(coal)

Your call on which implementation you want to use, the HashMap wrote is simpler and less code to write with the trade-off of less performance and increased memory use.

yokuyuki
  • 98
  • 1
  • 1
  • 6