当前位置 : 主页 > 大数据 > 区块链 >

如何有效地在ProtoBuf中建模HashMap / Dictionary

来源:互联网 收集:自由互联 发布时间:2021-06-22
我有一个由.NET代码序列化的protobuf文件,我想将它用于 Java.在.NET代码中,有Dictionary数据类型,proto架构看起来像 message Pair { optional string key = 1; optional string value = 2;}message Dictionary { repeated
我有一个由.NET代码序列化的protobuf文件,我想将它用于 Java.在.NET代码中,有Dictionary数据类型,proto架构看起来像

message Pair {
   optional string key = 1;
   optional string value = 2;
}

message Dictionary {
   repeated Pair pairs = 1;
}

正如stackoverflow帖子中所描述的那样
Dictionary in protocol buffers.

我可以使用protoc将proto文件编译成Java类.我可以成功地将protobuf文件反序列化为Java对象.唯一的问题是它转换为Java中的Pair对象列表而不是HashMap.当然,我仍然拥有所有数据,但我无法按照自己的喜好有效地访问数据.如果我有键的值,我必须遍历整个列表以获得其对应的值.这似乎不是最佳的.

我想知道是否有更好的方法来模拟protobuf中的字典/地图数据类型.

谢谢

更新:

我试过Jon Skeet的建议,在地址簿示例中添加地图类型字段,但仍然遇到问题.

message Person {
  required string name = 1;
  required int32 id = 2;        // Unique ID number for this person.
  optional string email = 3;
  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }
  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }
  repeated PhoneNumber phone = 4;
  map<string, string> mapdata = 5;
}

protoc在编译时抛出错误

addressbook.proto:25:3: Expected "required", "optional", or "repeated".
addressbook.proto:25:6: Expected field name.

根据Google protobuf doc,proto 2支持地图类型https://developers.google.com/protocol-buffers/docs/proto#maps.正如我所说,

Maps cannot be repeated, optional, or required.

所以我真的不知道为什么protoc无法编译它.这里有另一个讨论have to create java pojo for the existing proto includes Map.答案表明地图只是一个原型3的特征.这与google的文档相矛盾.

好吧, maps are already supported in “protobuf proper” as of v3.0.例如,您的原型是有效的:

message Dictionary {
    map<string, string> pairs = 1;
}

好消息是,使用您定义的键和值字段,它与您现有的数据完全向后兼容:)

坏消息是我不知道protobuf-net是否支持它.如果您实际上没有在.NET端使用.proto文件,并以声明方式执行所有操作,您可能只能修改.proto文件,重新生成Java代码,然后…

剩下的坏消息是地图是在v3.0中引入的,在撰写本文时仍处于alpha / beta状态.现在,根据您需要发布的时间,您可能会决定在您需要的时候下注v3.0 – 在我看来,拥有漂亮的地图语法的好处非常重要.目前正在进行的大多数更改都围绕着新的proto3功能 – 而在proto2语法文件中也允许使用地图……只需要v3.0编译器和运行时就可以使用它们.

网友评论