我在HashSet上調用Iterator.remove()時遇到了問題。HashSet.remove()和Iterator.remove()不起作用
我有一組時間戳對象。在向Set中添加新項目之前,我循環遍歷該組,識別該數據對象的舊版本並將其刪除(在添加新對象之前)。時間戳包含在hashCode和equals()中,但不包含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中的斷點,它仍然無法更改設置的狀態DataResult是一個不可變的對象,因此它最初添加到集合後不能更改。
equals和hashCode()方法使用@Override來確保它們是正確的方法。單元測試驗證了這些工作。
這也失敗,如果我只是使用for語句和Set.remove來代替。 (例如遍歷項目,找到列表中的項目,然後在循環後調用Set.remove(oldData))。
我在JDK 5和JDK 6
測試,我想我必須失去了一些基本的東西,但花一些時間顯著在這我的同事後,我被難住了。任何建議要檢查的東西?
編輯:
已經有問題 - 是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哈希碼已更改。
非常微妙 - 我看了很多次,並沒有注意到缺乏不變性。
兩種可能性。你說DataResult是不可變的。假設值由構造函數設置並且沒有設置方法是否安全? 2.你的equals和hashcode不能按照你的預期工作。你可以發佈這兩個代碼嗎? – 2008-10-31 21:31:50