Может кто-нибудь объяснить, почему HashMap ведет себя так, как в этом примере:
Простой тест, который проверяет хэш-карту на наличие ключа. Один раз в конструкторе и один раз в методе ListDataListener intervallAdded.
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import com.jgoodies.common.collect.ArrayListModel;
public class Test1 {
private final Listener listener = new Listener();
private final Map<List<?>, Object> parentByCollection = new HashMap<List<?>, Object>();
public Test1(){
ArrayListModel<Object> list = new ArrayListModel<Object>();
list.addListDataListener(listener);
parentByCollection.put(list, new Integer(10));
// Test containsKey locally
System.out.println("Item exists (locally):" + parentByCollection.containsKey(list));
// Test containsKey via ListDataListener
list.add(new Integer(20));
}
/**
* @param args
*/
public static void main(String[] args) {
new Test1();
}
public class Listener implements ListDataListener{
@Override
public void intervalAdded(ListDataEvent e) {
List<?> itemSource = (List<?>)e.getSource();
System.out.println("Item exists (listener):" + parentByCollection.containsKey(itemSource));
}
@Override
public void intervalRemoved(ListDataEvent e) {
}
@Override
public void contentsChanged(ListDataEvent e) {
}
}
}
Почему хэш-карта возвращает false из события, но true из конструктора при использовании containsKey? Есть ли какая-то «магия» java-дженериков, о которой я здесь не знаю?
Редактировать:
Только что обнаружил, что метод hashCode ArrayList (который расширяет ArrayListModel) собирает свой хэш-код из всех его элементов. Это означает, что хэш-код меняется с элементами в списке. Так что хранить ArrayList в HashMap не очень хорошая идея.
Как я могу это решить? Вместо этого хранить коллекции в объекте держателя/контейнера?
com.jgoodies.common.collect.ArrayListModel
. - person Stan Kurilin   schedule 13.03.2011