redsh1rt
redsh1rt

Reputation: 33

Get an Object's Property from HashMap Value

I'm working on a text based adventure game in Java, and I'm trying to figure out a way to check what weapon the player has and set their damage output appropriately.

Here is what I have set up so far:

Item object:

Item (String name, String type, String description, String location)

("Assault Rifle", "rifle", "A rifle that goes pew pew.", "armory")

Player inventory:

HashMap<String, Item> inventory = new HashMap<String, Item>()

Right now, I can use an if statement to grab the name of the object, and set the damage modifiers for it:

if (player.getInventory().containsKey("Assault Rifle")) {
        player.setMaxAttackDmg(55);
        player.setWeaponModifier(2);
    }

What I want to be able to do is match on the item type, and not the name. I'm assuming I need a loop of some kind to iterate through the player's inventory, but I don't know how I match the HashMap value since it is an object of type Item. So it would have something like:

for (item in inventory) {
    if (item.getType().equals("rifle")) {
        player.setMaxAttackDmg(55);
        player.setWeaponModifier(2);
    }

Is there way to do that, or a better way for me to do this?

Upvotes: 0

Views: 1412

Answers (3)

stridecolossus
stridecolossus

Reputation: 1561

You can iterate through the values of the map to retrieve the items and then apply your test:

public Item find(String type) {
    for(final Item item : inventory.values()) {
        if(item.type().equals(type)) {
            return item;
        }
    }
    return null; // or throw an exception
}

It's certainly not the most OO approach ;) but it does what you want.

You might want to look at the other accessors of the map class such as keySet and entrySet for other ways to 'view' the inventory.

Once you have something working you might also want to investigate Java8 streams which support this sort of functionality in a much more elegant and readable way.

Upvotes: 2

Yayotr&#243;n
Yayotr&#243;n

Reputation: 1869

You already know how to do it using loop, your approach works.

A better way to retrieve this value from a Map is to use a stream and filter out for the first occurrence, and then perform an action if the player has this on his inventory.

For example:

inventory.values()
    .stream()
    .filter(item -> item.type().equals(type))
    .findFirst()
    .ifPresent(item -> /*your action*/);

Additionally, I'd recommend you refactor your code in a more object-oriented way, for example based on the snippet you provide you could create a sub-class of Item called Weapon and have a method in Person to equip your weapon and increase your stats, e.g:

  private void equipWeapon(Weapon weapon){
    player.setMaxAttackDmg(weapon.getAttackDamage());
    player.setWeaponModifier(weapon.getModifier());
  }

Upvotes: 1

Abhijit Sarkar
Abhijit Sarkar

Reputation: 24518

I’d make a Weapon Enum with properties like maxAttackDmg. Then you can simply get the properties on the enum without knowing what instance it is. If weapons need to have complex behavior, and are more than just data classes, then those should be regular classes, not enum.

Upvotes: 1

Related Questions