2009-12-09 18 views
4

這是我的用例,我有一個邏輯上等於我的HashMap鍵但不是相同的對象(不是==)的對象。我需要從HashMap中取出實體關鍵對象,以便我可以同步它。我知道我可以遍歷ketSet,但與哈希相比,這是緩慢的。爲什麼getEntry(Object key)不公開在HashMap上?

通過java.util.HashMap實現,我看到了一個getEntry(Object key)方法,它正是我所需要的。任何想法爲什麼這沒有被暴露?

你能想到任何其他方式我可以得到鑰匙嗎?

+0

你可以通過反思得到它,如果沒有其他方法,仍然可以使用。 – Geo 2009-12-09 11:38:56

+0

邏輯上等於=等於方法被覆蓋? HashMap始終使用equals而不是==。 通常不鼓勵使用可變對象作爲關鍵類。 – dmeister 2009-12-09 11:40:20

+0

@Geo:我會懷疑使用反射來獲取同步對象;部分原因是由於性能上的擔憂,但主要是因爲非常量對象的顯式同步無論如何都很難實現,不要介意何時通過反射來不透明地獲取該引用。這很可能會很難理解,跟蹤和調試,使維護成爲一場噩夢。 – 2009-12-09 11:42:17

回答

4

我認爲你會更好地在價值上增加額外的間接層。關鍵還應該是一個「純粹」的價值。相反的:

Map<ReferenceObjectKey,Thing> map; 

用途:

Map<ValueObjectKey,ReferenceObject<Thing>> map; 
+0

這可能不一定是這裏的問題 - 例如,字符串鍵仍然會導致上面聲明的相同問題(除非你'實習所有的絃樂,這是一個壞主意];而我從來沒有聽過有人說弦是不合適的地圖鍵。 – 2009-12-09 12:01:43

+0

我不關注。 'String's是我書中的值對象。 – 2009-12-09 12:34:21

+0

我在說這個問題仍然存在於字符串和其他值對象中;您提出的解決方案不能解決問題(因爲querent構成的問題不是需要解決的問題)。 – 2009-12-09 14:11:53

0

這聽起來像是一個更深層次的問題。你爲什麼需要這樣的事情?爲什麼關鍵不是唯一的對象?

你是什麼意思,「所以我可以同步它」?

+0

我懷疑希望什麼是所有對同等對象的調用(即,將映射到散列映射中的同一個鍵*),以獲得對同步的一致對象實例的訪問。 querent沒有說他爲什麼要這樣做,但這聽起來像是某種嘗試阻止兩個線程一次修改給定鍵的映射。 – 2009-12-09 11:52:33

+0

我認爲你是對的。使用ConcurrentHashMap可以解決他的問題,如果關於該問題的假設是正確的,當然:) – 2009-12-09 12:15:27

3

我不能回答你真正的問題(爲什麼方法沒有公開),而不是顯而易見的,「因爲作者決定不公開它。」

然而,你的問題使我相信你有一個相當奇怪的同步方案正在進行;從我的理解中,你只是試圖調用它來獲得用於同步的同等對象的規範表示。這聽起來像一個非常糟糕的主意,正如我在對問題的評論中指出的那樣。

更好的方法是重新考慮如何以及爲什麼要在這些關鍵對象上進行同步,並將同步更清晰,更好地完成,最好是在更高級別或完全使用替代方法。

如果你發佈了一個你想要做這個同步的代碼片段,這樣其他人可以通過一個更清晰的方式來實現它,這可能會有所幫助。一個例子就是使用線程安全的地圖類(如ConcurrentHashMap),如果這確實是你想要在這裏實現的。

編輯:看看How To Ask Questions The Smart Way,特別是我已經鏈接的重點,因爲這是一個經典的例子。看起來您的整體設計可能有點偏離,需要朝另一個方向發展;所以當你陷入這個特定的問題時,這是一個更大問題的症狀。給我們更廣泛的背景將導致你得到更好的整體答案。

-1

我很抱歉,但你似乎在這裏有一個概念上的突破。

如果您的問題是您「等待」一個等效對象(.equals()爲true,但==爲false)到一個鍵,並且需要找到該鍵,那麼使用get的Object變體將無濟於事你,因爲Object支持的唯一的.equals是identity(==)。

你需要做的是在你的關鍵類中實現equals()和hashcode()。

這將使它獲得條目的微不足道。

+0

當然,我已經實現了equals和hashcode。我的問題說明 – 2009-12-12 17:54:57

2

實際上,來電者要求的方法將是有益的。這可能是一個錯誤,它或者類似的東西不包括在內。

正因爲如此,假設你想增加這是一個從密鑰「a」對應的整數值 - 你最終不得不做「一」兩次哈希查找。假設您想區分不存在的值和存在的值,但將其映射到空值 - 再次是兩個哈希查找。

在實踐中,世界上還沒有因爲這樣結束了,雖然。

1

最近我自己最近偶然發現了這個問題。當我把問題解決得足夠的時候,我基本上使用了兩種不同的方法將數據與用於確定相等性的關鍵對象的部分相關聯。

  • 隨着鍵映射到的值,經由地圖
  • 與包含與密鑰對象中的數據,但沒有在.equals()/ hashCode方法中使用,通過組合物。

我在密鑰類中使用List來確定相等和哈希碼,並且其中有3個其他字段 - 一個布爾值和2個字符串。最後,我重拍的地圖作爲地圖<列表<字符串> ...>和重構了其他3場到自己的類,然後有原始類的列表的組成和新類。我覺得在這之後代碼看起來更好。

相關問題