在我的Android应用程序中,我有一个只包含数据的类(使用getter公开)。这个类需要被序列化并发送到其他客户端(通过遍历所有getter并将它们存储在ByteBuffer中来天真地完成)。
public class Data
{
public int getOption1() { }
public int getOption2 { }
// ...
public int getOptionN { }
}
序列化:
public void serialize(Data data) {
// write getOption1();
// write getOption2();
// ...
}
反序列化:
public void deserialize() {
// read Option1();
// read Option2();
// ...
}
我希望能够定义实际发送的字段(而不是盲目地发送所有字段),并且一个可能的解决方案是定义另一个字段bitmask
来定义哪个字段字段实际上已发送。
接收端解析位掩码,并且可以从接收的消息中分辨出哪些字段应该反序列化。
问题是 - 对位掩码使用int(32位)只允许32个唯一选项(使用2个枚举值的“标准”幂)。
如何定义一个可以支持更多项目的位掩码?有没有其他编码(除了将每个值存储为2的幂)?
实际值的数量可能会有所不同(取决于用户输入),可能是~50到200之间的任何值。
我想用最有效的编码对不同的选项进行编码。
答案 0 :(得分:4)
int
为32个选项中的每一个提供了一点。您可以使用long
来获取64个选项中的每一个。对于大量选项,您可以使用int
或long
数组。取选项数量除以32(对于int
数组)或64(对于long
数组)并向上舍入。
byte
数组将提供最少的浪费。将选项数除以8并向上舍入。您可以保留第一个字节以包含字节数组的长度(如果您也传递其他数据)。由于Byte.MAX_VALUE
为127(但您可以将该值视为最大有效索引,而不是字节数),这会将您限制为128 * 8 - 1 = 1023个选项(如果您愿意,可以选择2047个选项)处理负字节计数值的额外工作很少)。最大浪费将少于一个字节(加上额外的字节开销来存储计数)。
如果每个选项可以独立存在,那么你就无法做得更好。如果可以对选项进行分组,使得组中的所有选项始终全部存在或全部不存在,则可能会进行一些额外的压缩。