HashMap с ключом ArrayList не может найти его при росте Arraylist - PullRequest
1 голос
/ 07 января 2012

Что ж, моя проблема в том, что в некоторой части моего кода я использую arraylist в качестве ключа в хэш-карте, например,

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

И затем я помещаю свой массив как ключ в хэш-карту (ямне нужно это таким образом, я в этом уверен)

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

Вот и возникает проблема: когда я добавляю какое-то значение в свой массив, а затем пытаюсь восстановить данные, используя тот же массив, что и хэш-картуя не могу его найти.

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

В это время значение равно нулю вместо строки "value1", которую я тестировал, и обнаружил, что hashCode изменяется, когда растет список массивов, и это является центральной точкой моей проблемы,но я хочу знать, как я могу это исправить.

Ответы [ 6 ]

3 голосов
/ 07 января 2012

Используйте IdentityHashMap.Тогда тот же экземпляр массива всегда будет отображаться на одно и то же значение независимо от того, как изменяется его содержимое (и, следовательно, хэш-код).

1 голос
/ 07 января 2012

Вы не можете использовать изменяемый объект (то есть тот, чей hashCode изменяется) в качестве ключа HashMap. Посмотрите, сможете ли вы найти что-то еще, чтобы использовать вместо этого ключ. Несколько необычно отображать коллекцию в строку; обратный путь встречается гораздо чаще.

0 голосов
/ 06 марта 2018

Основная причина: когда мы используем HashMap.put (k, v), он будет обозначать k.hashCode (), чтобы он мог знать, где его разместить.

И он также находит значение по этому номеру (k.hashCode ());

Вы можете увидеть функцию ArrayList.hashCode (), которая находится в абстрактном классе AbstractList.Очевидно, что после добавления какого-либо объекта он изменит значение haseCode.Поэтому мы не можем найти значение, используя HashMap.get (K), и нет элемента, для которого hashCode имеет значение K.

public int hashCode() {
    int hashCode = 1;
    for (E e : this)
        hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
    return hashCode;
}
0 голосов
/ 07 января 2012

На мой взгляд, это немного сложнее, чем попытаться сделать.

Я предполагаю, что вы пытаетесь смоделировать ключ переменной длины, состоящий из n целых чисел, иПредположим, что хэш ArrayList будет согласованным, но я не уверен, что это так.

Я бы посоветовал вам либо подкласс ArrayList и переопределить hash() & equals()методы, или оберните HashMap в ключевой класс.

0 голосов
/ 07 января 2012

Я почти уверен, что вы не захотите этого делать.Скорее всего, вы захотите Map<String, List<Integer>>.Однако, если вы абсолютно должны сделать это, используйте класс держателя:

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

Map<ListHolder, String> map = new HashMap<ListHolder, String>;
0 голосов
/ 07 января 2012

Это странный вариант использования, но если вы должны это сделать, вы можете создать подкласс массива и переопределить метод hashCode.

...