【问题标题】:Creating a bitmask with a large number of options创建具有大量选项的位掩码
【发布时间】:2013-10-30 23:07:15
【问题描述】:

在我的 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 之间。

我想以最有效的编码方式对不同的选项进行编码。

【问题讨论】:

    标签: java android serialization bit-manipulation bitmask


    【解决方案1】:

    int 为 32 个选项中的每一个提供一个位。您可以使用long 来获取 64 个选项中的每一个选项。对于更多的选项,您可以使用intlong 数组。取选项的数量,除以 32(int 数组)或 64(long 数组)并向上取整。

    byte 数组将提供最少的浪费。将选项数除以 8 并向上取整。您可以保留第一个字节以包含字节数组的长度(如果您还要传递其他数据)。由于Byte.MAX_VALUE 是 127(但您可以将该值视为最大有效索引,而不是字节数),这将您限制为 128 * 8 - 1 = 1023 个选项(如果您愿意做一些额外的事情,则为 2047 个选项处理负字节计数值)。最大浪费将小于一个字节(加上一个额外的字节来存储计数)。

    如果每个选项都可以独立存在或不存在,那么您将无法做得更好。如果可以对选项进行分组,使得组中的所有选项始终全部存在或全部不存在,则可以进行一些额外的压缩。

    【讨论】:

    • 您是如何获得 1023 个选项的?数组的大小应该是多少?
    • @lysergic-acid - 您可以在 byte 中存储的最大计数为 127(因为 byte 在 Java 中是一个有符号值)。这限制了您在计数字节之后可以拥有的字节数。如果要允许负字节值,则数组中最多可以有 255 个字节;但是,您需要做一些额外的处理才能将负值视为正值。一种方法是向上转换和掩蔽;另一种是使用有偏差的计数。 (这些是不同的方法;您可以使用其中一种。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    相关资源
    最近更新 更多