2014-03-03 47 views
0

我有一個包含幾何形狀(通常是(多)行)的集合的幾何形狀。現在我想爲這些幾何實現一個HashCode,以便將它們放入集合中。爲此,我在每個幾何體中都有三個成員不會更改,因此適用於HashCode:幾何體類型(對於所有幾何體,起點和終點,PolyLine)的哈希碼,只有不同對他們的方向

所以我寫了這個代碼

int hash = 17; 

// this hascode-implementation uses the geometry-type and the from- and toPoints of the geometry 

hash = hash * 31 + this.Geometry.GeometryType.GetHashCode(); 
hash = hash * 31 + this.Geometry.FromPoint.X.GetHashCode(); 
hash = hash * 31 + this.Geometry.FromPoint.Y.GetHashCode(); 
hash = hash * 31 + this.Geometry.ToPoint.X.GetHashCode(); 
hash = hash * 31 + this.Geometry.ToPoint.Y.GetHashCode(); 

現在我們有這使得它無法給我寫一個哈希函數我們的應用程序中的另一個前提條件:兩個幾何圖形也被認爲是相等的時候都相反。由於每個實際的平等對象必須具有相同的hashCode,我必須更改實現,以便允許對角線衝突。

這意味着以下內容:

當幾何1的fromPoint從幾何2(反之亦然)等於尖山也其散列碼必須相等。

哪我有我的執行來改變,使斜碰撞或我完全whrong我的執行的因素/有沒有更好的方式來做到這一點)?

回答

0

對於交換點以產生相同的結果,您需要一個數學運算,其中A op B == B op A和您需要將它應用於兩個座標之前將結果添加到哈希。

我想試試這個:

hash = hash * 31 + (
     this.Geometry.FromPoint.X.GetHashCode() 
     + this.Geometry.ToPoint.X.GetHashCode 
); 

此行返回相同的結果,無論在哪個命令你傳遞的X座標。

注意:如果您添加/刪除多邊形的線條或移動終點,然後哈希代碼更改。因此,只要這樣的對象存儲在哈希映射/集合中,就必須確保幾何不會更改。

如果您需要更改的幾何形狀,你首先必須從哈希表/集刪除對象,改變形狀,然後重新添加。

PS:在你的代碼的最後一行XY

+0

葉氏,就是這樣,簡單的數學,並感謝您的編輯建議:d – HimBromBeere

0

我還沒有真正瞭解你所描述的問題的幾何方面,但這裏有幾個想法:

  • 多少對象你有嗎?如果它的東西,適合沒有太多,這或許可以被接受並不過分擔心的哈希碼實現,只是讓恆

  • 如果有兩個幾何的equals操作是不平凡的,怎麼樣把它們包裝成一個你沒有什麼問題談論平等的對象?例如new MyGeometry("an Id", aGeometry)?實現hashCode/equals應該是微不足道的。

+0

我也有你的第二個方法,但這裏的問題是:我怎麼產生這些ID,當兩個幾何相等?我必須檢測它們是否相同,所以我可以給它們相同的ID,不是嗎? Btw .:這個問題與JAVA(僅)無關,因爲其他語言也有hashCode。所以我沒有用JAVA標記它...... – HimBromBeere

+0

那麼,取決於你需要什麼等於操作。擁有一個'MyGeometry'集合並手動實現插入操作(是否需要刪除或不刪除?)當然是可以接受的。 –

+0

@HimBromBeere:jan groth的意思是允許你從'hashCode()'返回一個常量值(比如'5')。然後將使用equals()來區分這些對象。但是如果你有很多物體,那會很慢。 –

相關問題