yuryeuceda
yuryeuceda

Reputation: 11

HashMap with ArrayList key can not find it when Arraylist grows

Well my problem is that in some part of my code I use an arraylist as a key in a hashmap for example

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

And then I put my array like a key in a hash map (I need it in this way I'm sure of that)

HashMap<ArrayList<Integer>, String> map = new HashMap<ArrayList<Integer>, String>();
map.put(array, "value1");

Here comes the problem: When I add some value to my array and then I try to recover the data using the same array then the hash map cant find it.

array.add(23);
String value = map.get(array);

At this time value is null instead of string "value1" I was testing and I discovered that the hashCode changes when array list grows up and this is the central point of my problem, but I want to know how can I fix this.

Upvotes: 1

Views: 704

Answers (6)

qinghua
qinghua

Reputation: 117

The basic reason: When we use HashMap.put(k, v), it will digit k.hashCode() so that it can know where to put it.

And it also find the value by this number(k.hashCode());

You can see the ArrayList.hashCode() function and it is in the abstract class of AbstractList. Obviously, after we add some object, it will change the haseCode value. So we can not find the value use HashMap.get(K) and there is no element which hashCode is K.

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}

Upvotes: 0

Bohemian
Bohemian

Reputation: 425013

I'm almost certain you would not want to do that. It's more likely you would want a Map<String, List<Integer>>. However, if you absolutely must do this, use a holder class:

public class ListHolder {
    private List<Integer> list = new ArrayList<Integer>();
    public List<Integer> getList() {return list;}
}

Map<ListHolder, String> map = new HashMap<ListHolder, String>;

Upvotes: 0

Lee
Lee

Reputation: 921

Its a bit of an add thing to try and do in my opinion.

I assume what you are trying to model is a variable length key made up of n integers, and assume that the hash of the ArrayList will be consistent, but I'm not sure that is the case.

I would suggest that you either subclass ArrayList and override the hash() & equals() methods, or wrap the HashMap in a key class.

Upvotes: 0

Russell Zahniser
Russell Zahniser

Reputation: 16364

Use an IdentityHashMap. Then that same array instance will always map to the same value, no matter how its contents (and therefore hash code) are changed.

Upvotes: 3

Usman Ismail
Usman Ismail

Reputation: 18659

Its a weird use case but if you must do it then you can sub class the array and override the hashCode method.

Upvotes: 0

Taymon
Taymon

Reputation: 25676

You can't use a mutable object (that is, one whose hashCode changes) as the key of a HashMap. See if you can find something else to use as the key instead. It's somewhat unusual to map a collection to a string; the other way around is much more common.

Upvotes: 1

Related Questions