Нулевое значение при переборе набора ключей Hash - PullRequest
2 голосов
/ 24 июня 2011

Меня удивляет, как следующий сегмент может привести к нулевому значению логического значения обязательно, хотя он не равен нулю при соответствующем ключе в фактической хеш-таблице:

for (List<List<A>> a : hashMap.keySet()) {  
    Boolean mandatory = hashMap.get(a);
}

Ответы [ 3 ]

2 голосов
/ 24 июня 2011

HashMap вернет null , если указанный ключ не привязан к значению .

Почти наверняка проблема заключается в том, что операция сравнения в a - Список -против ключей не получается.

Позвольте мне угадать: вы изменяете эти списки (ключевой объект) после того, как вы вызвали пут?Вы удалили все записи в одном из ключей?Помните, что пустой список equal для всех пустых списков массивов.Кроме того, помните, что List.equals () сравнивает содержимое списка (по одному) с проверкой равенства.

package sof_6462281;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Demonstrate the fact that the Map uses key.equals(k) to
 * test for key equality.  Further demonstrate that it is a 
 * very bad idea to use mutable collections are keys to maps.
 */
public class ListAsKey {
    public static void main(String[] args) {
        Map<List<A>, Boolean>  map = new HashMap<List<A>, Boolean>();

        List<A> alist = new ArrayList<A>();
        map.put(alist, true);
        for (List<A> a : map.keySet()) {
            Boolean b = map.get(a);
            System.out.format("\t%s(ArrayList@%d) => %s\n",a, a.hashCode(), map.get(a)); 
        }

        // you changed your list after the put, didn't you?
        alist.add(new A());
        for (List<A> a : map.keySet()) {
            Boolean b = map.get(a);
            System.out.format("\t%s(ArrayList@%d) => %s\n",a, a.hashCode(), map.get(a)); 
        }

        alist.clear();
        for (List<A> a : map.keySet()) {
            Boolean b = map.get(a);
            System.out.format("\t%s(ArrayList@%d) => %s\n",a, a.hashCode(), map.get(a)); 
        }
    }
    public static final class A { /* foo */ }
}

Результаты:

[](ArrayList@1) => true
[sof_6462281.ListAsKey$A@4b71bbc9](ArrayList@1265744872) => null
[](ArrayList@1) => true

edit: добавлены дополнительные операции в вышеупомянутую и добавлена ​​консольвне.

0 голосов
/ 24 июня 2011

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

Менее вероятный, но возможный сценарий, даже если предположить, что вы каким-то образом не испортили свой ключ List<List<>>, если вы испортили метод equals класса A, то метод equals вашего Списка также будет испорчен, снова испортить вашу карту.

Посмотрите на хороший пример кода alphazero, если вам нужны дополнительные доказательства того, что то, что вы пытаетесь сделать, является плохой идеей.

0 голосов
/ 24 июня 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...