ArrayList as HashMap keys

Hi All,

I have a HashMap that uses an ArrayList of Integer objects as it's keys (i.e. the HashMap is declared to be HashMap<ArrayList><Integer>,Object o> ). I remove the integers from the ArrayList one by one as required, until the ArrayList is empty. When The ArrayList is empty I want to remove the entry from the HashMap.

The sample program below demonstrates the problem. The program knows the key is an empty ArrayList, however it is unable to remove it, instead returning null, which from the documentation would indicate that there is no mapping for the key. How can I remove the object?

import java.util.*;

publicclass HashMapTest{

public HashMap<ArrayList><Integer>,ArrayList<String>> hashmap;

publicstaticvoid main(String[] args){

new HashMapTest();

}

/*Setup initial values, and the remove integers*/

public HashMapTest(){

hashmap =new HashMap<ArrayList><Integer>,ArrayList<String>>();

ArrayList<Integer> dependancies =new ArrayList<Integer>();

dependancies.add(1);

dependancies.add(2);

ArrayList<String> tasks =new ArrayList<String>();

tasks.add("TASK 1");

tasks.add("TASK 2");

hashmap.put(dependancies,tasks);

ArrayList<Integer> dependancies2 =new ArrayList<Integer>();

dependancies2.add(2);

dependancies2.add(3);

ArrayList<String> tasks2 =new ArrayList<String>();

tasks2.add("TASK 3");

tasks2.add("TASK 4");

hashmap.put(dependancies2,tasks2);

//NOW RETURN JOB 1;

System.out.println(hashmap);

removeInt(hashmap,2);

removeInt(hashmap,1);

System.out.println(hashmap);

hashmap.remove(new ArrayList<Integer>());

System.out.println(hashmap);

}

publicvoid removeInt(HashMap<ArrayList><Integer>, ArrayList<String>> m,int jobReturned){

int mapsize = m.size();

Integer myInt = jobReturned;

HashMap map = m;

Iterator<Map.Entry><ArrayList><Integer>,ArrayList<String>>> keyValuePairs1 = map.entrySet().iterator();

for (int i = 0; i < mapsize; i++)

{

Map.Entry<ArrayList><Integer>,ArrayList<String>> entry = keyValuePairs1.next();

ArrayList<Integer> key = entry.getKey();

ArrayList<String> value = entry.getValue();

if(key.contains(myInt)){

key.remove(myInt);

}

if(key.isEmpty()){

System.out.print("Key is: ");

System.out.println(key);

System.out.println("Returned at removal" + map.remove(key));

}

}

}

}

All help gratefully received,

TIA

Adam

[4150 byte] By [chester122a] at [2007-11-26 16:45:02]
# 1

Well, the problem is that you are modifying the ArrayList while it is already stored as key in the HashMap. The HashMap uses the hashCode of a key to store it into a bucket. As the ArrayList's hashCode is computed based on its content, i.e., it's entries, after modifying the ArrayList, it has a different hashCode and thus cannot be found in the Map.

stefan.schulza at 2007-7-8 23:12:21 > top of Java-index,Core,Core APIs...
# 2
Is it possible then that I might get around the problem by asking the HashMap to re-hash after each removal?
chester122a at 2007-7-8 23:12:21 > top of Java-index,Core,Core APIs...
# 3
How would you do that?I am quite sure that your design is no good style, but, of course, it may be what you want to have. You should not use Objects with mutable hashCode as keys in a map, if you modify those Objects.
stefan.schulza at 2007-7-8 23:12:21 > top of Java-index,Core,Core APIs...
# 4
you could use an [url= http://java.sun.com/j2se/1.5.0/docs/api/java/util/IdentityHashMap.html]IdentityHashMap[/url]
georgemca at 2007-7-8 23:12:21 > top of Java-index,Core,Core APIs...
# 5
Good catch, george. I had a complete tunnel vision on the OP using HashMap.
stefan.schulza at 2007-7-8 23:12:21 > top of Java-index,Core,Core APIs...