2016-01-11 16 views
-1

我們可以使用protobuf類(由protobuf編譯器生成的對象)作爲HashMaps中的鍵。Protobuf對象作爲地圖中的鍵

hashCode()是如何在protobuf類上實現的。 hashcode()方法是否足夠好以避免大部分時間發生衝突。

+1

什麼阻止你測試它? – redFIVE

+0

我不熟悉這些「protobuf類」,但不能只看它們,看看它們是否實現了'hashcode()'(和'equals')? –

+1

簡答:是的。 –

回答

2

是的,你可以使用協議緩衝區作爲散列鍵。協議緩衝器消息類型實施Message,其中specifies是依賴於內容的equalshashCode實現。

+0

感謝您指向要檢查的文檔。但是,看起來它沒有在那裏實現。 int hashCode() 返回此消息的哈希碼值。消息的哈希碼應該混合消息的類型(描述符的對象標識)與其內容(已知和未知的字段值)。子類必須實現這個;繼承Object.hashCode()不正確 –

3

你可以,但你應該知道這樣做有問題。在Proto2中,可選字段和擴展可能會導致一些令人驚訝的效果。例如,請考慮以下原型:

message Foo { 
    optional string bar = 1; 
} 

,並考慮以下代碼:

Foo thing1 = Foo.newBuilder().setBar("").build(); 
Foo thing2 = Foo.getDefaultInstance(); 

Set<Foo> s = new HashSet<>(); 
s.add(thing1); 
s.add(thing2); 

會有什麼的s規模有多大?在這種情況下,這將是2,但如果你比較每個字段直接,你會發現它們是相同的:

assertEquals(thing1.getBar(), thing2.getBar()); // true 

所有兩個字段具有相同的價值,但他們不會比較相等。即使默認值與設定值相同,equalshashCode方法也會考慮是否設置字段。這也是爲什麼你有時會看到單元測試報告說當兩個原型表示相同時,兩個原型不相同。

要考慮的另一件事是Protobuf擴展對兩個原型之間的平等有影響。如果使用擴展註冊表解析相同的原型並且沒有一個,則兩個表示不會相等。這可能令人驚訝,因爲它們的編碼線格式是相同的,並且都被解析爲相同的消息類型。在沒有和擴展註冊表解析的情況下,額外的數據將顯示在未知字段中。

如果你知道Protobuf是如何工作的話,這一切都很明顯,但對於新手來說可能並非如此。