HashMap question

Discussion in 'Plugin Development' started by EdTheLoon, Aug 17, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    EdTheLoon

    What is the best way to remove an entry in a HashMap when all you have is the value of something stored in the HashMap? someHashMap.remove(...) wouldn't work because it requires the key rather than the value. The reason I wouldn't have access to the key is because I need an entity ID (which is stored in the value of the hashmap) removed from a HashMap when the entity is destroyed. Also, I am aware that HashMap's may contain duplicate values but there will be no duplicates in my HashMap so that isn't a concern. I'm thinking that I'm going to have to clone the contents of the hashmap to a different type and then loop through the values.
     
  2. Offline

    Lolmewn

    Im guessing you have to use keySet(). Otherwise I really wouldn't know how to get it :p
     
  3. Offline

    EdTheLoon

    So using keySet I could possibly do values() to get a list of the values, iterate through it and track where I am in the collection with variable x. Once I've found the value I need I could then get the key at index x and then use remove() to remove it from the HashMap.
     
  4. Offline

    oz_revulsion

    The only way I can think of is to iterate through the HashMap and compare the values. Like this:

    Code:
    Iterator it = mp.entrySet().iterator();
    ArrayList<String> removeList = new ArrayList<String>();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry)it.next();
        if (pair.getValue() == "whatchulookinfor")
        {
             removeList.add(pair.getKey());
        }
    }
    
    for (int i = 0; i < removeList.size(); i++) {
        mp.remove(removeList.get(i));
    }
    Before you ask as well the reason I get the list to remove and then actually remove them afterwards is because if you remove while you are iterating through the map you will make the iterator invalid and you could break the logic. Of course the logic above assumes you are removing multiple values but you mentioned that you are only looking for one value so if that is the case what you could do is this instead.

    Code:
    Iterator it = mp.entrySet().iterator();
    ArrayList<String> removeList = new ArrayList<String>();
    while (it.hasNext()) {
        Map.Entry pairs = (Map.Entry)it.next();
        if (pair.getValue() == "whatchulookinfor")
        {
            mp.remove(pair.getKey());
            break;
        }
    }
    Alternatively if you need to search based on both the key and entry values a lot then what you could do is build a little Map class yourself which maintains two Arrays side by side. You could give it a get function that will get based on either side and as long as when you where adding values or removing values you added or removed values on the other array at the corresponding index then you'd have yourself something pretty useful for this situation. Shouldn't take more than an hour to knock up either!

    Cheers
    Oz
     
  5. Offline

    masteroftime

    i'd use a foreach loop to iterate over the keys and check the values:

    Code:
    for(String s : list.keySet)
    {
        if(list.get(s) == ID)
        {
            list.remove(s);
        }
    }
    I don't know if the remove works inside the loop, if not save the key and remove it afterwards. That should be no problem when the value only exists once.
     
  6. Offline

    Brain

    If you find yourself being forced to look for a value inside a hashmap instead of a key it is a strong indication that your data structures need work.

    If the values in your hashmap are indeed unique as well you could create a second hashmap which has the values of your first hashmap as keys and the keys of the first as values.

    However if you only have hundreds of entries in your hashmap and you're not looking up values several hundred times per second you can go with the linear search approach without having to be concerned about bad performance hits.

    TL;DR: Unless your hashmap is huge or you look up values very often, linear iteration is OK.
     
    desht likes this.
  7. Offline

    EdTheLoon

    I shall try some of the solutions you guys have suggested later when I get back from work :) Thank you very much. I'll post my results later
     
  8. Offline

    nisovin

    Iterators have a remove() method that is designed to safely remove an element from the collection while iterating over it.
     
  9. Offline

    Brain

    Careful, this is not always true. The method is defined in the Iterator interface, yes, but not every implementation does support it.
    For HashMap it seems there is an implementation for the remove method:
     
Thread Status:
Not open for further replies.

Share This Page