У меня проблемы с Iterator.remove (), вызванным для HashSet.
У меня есть набор объектов с метками времени. Перед добавлением нового элемента в набор я перебираю набор, определяю старую версию этого объекта данных и удаляю ее (перед добавлением нового объекта). временная метка включена в hashCode и равна (), но не равна equalsData ().
for (Iterator<DataResult> i = allResults.iterator(); i.hasNext();)
{
DataResult oldData = i.next();
if (data.equalsData(oldData))
{
i.remove();
break;
}
}
allResults.add(data)
Странно то, что i.remove () молча завершается неудачей (без исключения) для некоторых элементов в наборе. Я подтвердил
Строка i.remove () фактически называется. Я могу вызвать его из отладчика прямо в точке останова в Eclipse, и он по-прежнему не может изменить состояние Set
DataResult является неизменным объектом, поэтому он не может быть изменен после первоначального добавления в набор.
Методы equals и hashCode () используют @Override, чтобы убедиться, что они являются правильными методами. Модульные тесты подтверждают эту работу.
Это также не работает, если я просто использую оператор for и Set.remove вместо этого. (например, перебрать элементы, найти элемент в списке, а затем вызвать Set.remove (oldData) после цикла).
Я тестировал в JDK 5 и JDK 6.
Я думал, что, должно быть, упускаю что-то простое, но потратив некоторое время на это, мы с коллегой зашли в тупик. Любые предложения для вещей, чтобы проверить?
EDIT:
Были вопросы - действительно ли DataResult неизменен. Да. Нет сеттеров. И когда объект Date извлекается (который является изменяемым объектом), это делается путем создания копии.
public Date getEntryTime()
{
return DateUtil.copyDate(entryTime);
}
public static Date copyDate(Date date)
{
return (date == null) ? null : new Date(date.getTime());
}
ДОПОЛНИТЕЛЬНОЕ РЕДАКТИРОВАНИЕ (некоторое время спустя):
Для записи - DataResult не был неизменным! Он ссылался на объект, который имел хеш-код, который изменялся при сохранении в базе данных (я знаю, что это плохая практика). Оказалось, что если DataResult был создан с временным подобъектом, а подобъект был сохранен, хэш-код DataResult был изменен.
Очень тонкий - я смотрел на это много раз и не заметил отсутствия неизменности.