我们可以使用protobuf类(从protobuf编译器生成的对象)作为HashMaps中的键。
如何在protobuf类上实现hashCode()。 hashcode()方法是否足够好以避免在大多数时间发生冲突。
答案 0 :(得分:4)
你可以,但你应该知道这样做有问题。在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
两者的所有字段都具有相同的值,但它们不会相等。即使默认值与设置值相同,equals
和hashCode
方法也会考虑是否设置了字段。这也是为什么你有时看到单元测试报告两个protos不相等,当他们的字符串表示是相同的。
另一件需要考虑的事情是Protobuf扩展对两个protos之间的平等有影响。如果使用扩展注册表解析相同的proto并且没有一个,则两个表示将不会相等。这可能令人惊讶,因为它们的编码线格式是相同的,并且都被解析为相同的消息类型。在proto解析没有和扩展注册表的情况下,额外的数据将显示在未知字段中。
如果您知道Protobuf是如何工作的,那么这一点就很明显了,但对新手来说可能并非如此。
答案 1 :(得分:2)
是的,您可以使用协议缓冲区作为哈希键。协议缓冲区消息类型实现Message
,specifies内容依赖equals
和hashCode
实现。