Reputation: 13588
Can we use protobuf class ( objects generated from protobuf compiler) as keys in HashMaps.
How is the hashCode() implemented on a protobuf class. Is the hashcode() method good enough to avoid collisions most of the time.
Upvotes: 8
Views: 6645
Reputation: 6628
You can, but you should be aware that there are issues with doing so. In Proto2, optional fields and extensions can cause some surprising effects. For example, consider the following proto:
message Foo {
optional string bar = 1;
}
And consider the following code:
Foo thing1 = Foo.newBuilder().setBar("").build();
Foo thing2 = Foo.getDefaultInstance();
Set<Foo> s = new HashSet<>();
s.add(thing1);
s.add(thing2);
What will the size of s
be? In this case, it will be 2, but if you compared each field directly you would find them the same:
assertEquals(thing1.getBar(), thing2.getBar()); // true
All the fields of the two have the same value, but they won't compare equal. The equals
and hashCode
methods take whether or not a field is set into account, even if the default value is the same as the set value. This also is why you sometimes see unit tests report that two protos are not equal, when their string representations are the same.
One other thing to consider is that Protobuf extensions have an effect on equality between two protos. If the same proto is parsed with an extension registry and without one, the two representations will not compare equal. This may surprising, since their encoded wire format is identical, and are are both parsed as the same message type. In the case of the proto parsed without and extension registry, the extra data will show up in the unknown fields.
This is all obvious if you know how Protobuf works, but may not be so to a newcomer.
Upvotes: 7
Reputation: 198023
Yes, you can use protocol buffers as hash keys. Protocol buffer message types implement Message
, which specifies a content-dependent equals
and hashCode
implementation.
Upvotes: 3