use*_*455 7 java scala protocol-buffers grpc
我们可以使用 protobuf 类(从 protobuf 编译器生成的对象)作为 HashMaps 中的键吗?
hashCode() 是如何在 protobuf 类上实现的。hashcode() 方法是否足以在大多数情况下避免冲突。
你可以,但你应该意识到这样做有问题。在 Proto2 中,可选字段和扩展可能会产生一些令人惊讶的效果。例如,考虑以下原型:
message Foo {
optional string bar = 1;
}
Run Code Online (Sandbox Code Playgroud)
并考虑以下代码:
Foo thing1 = Foo.newBuilder().setBar("").build();
Foo thing2 = Foo.getDefaultInstance();
Set<Foo> s = new HashSet<>();
s.add(thing1);
s.add(thing2);
Run Code Online (Sandbox Code Playgroud)
尺寸会s是多少?在这种情况下,它将是 2,但如果您直接比较每个字段,您会发现它们相同:
assertEquals(thing1.getBar(), thing2.getBar()); // true
Run Code Online (Sandbox Code Playgroud)
两者的所有字段都具有相同的值,但它们不会比较相等。该equals和hashCode方法采取现场是否被设置进去,即使默认值是一样的设定值。这也是为什么您有时会看到单元测试报告两个 proto 不相等,而它们的字符串表示形式相同的原因。
要考虑的另一件事是 Protobuf 扩展对两个 proto 之间的相等性有影响。如果使用扩展注册表解析相同的 proto 而没有扩展注册表,则两种表示将不会比较相等。这可能令人惊讶,因为它们的编码有线格式是相同的,并且都被解析为相同的消息类型。在没有和扩展注册表解析的 proto 的情况下,额外的数据将显示在未知字段中。
如果您知道 Protobuf 的工作原理,这很明显,但对于新手来说可能并非如此。