如何在单个值中表示4个布尔可能性

时间:2011-03-12 13:41:15

标签: java byte bit-manipulation bitwise-operators

我想在一个值中存储4个布尔值。例如, 我想要一个值,告诉一个人是否:

IsSingle
IsGraduate
IsMale
IsLookingForPartner

将它们存储在一个字节中是好的,可以分配4位,每个参数一个。如果该位设置为1,则该布尔参数为true。所以我可以做位移操作来找到所有都是真的。如果byte的值为111,则前三个参数为真。这是一个好方法吗?有没有更好的方法来实现这个?

我需要将此值存储为数据库中的单个参数。

8 个答案:

答案 0 :(得分:17)

位标志。

public static final int IsSingle = 1 << 0;
public static final int IsGraduate = 1 << 1;
public static final int IsMale = 1 << 2;
public static final int IsLookingForPartner = 1 << 3;

...

if ((Value & IsSingle) != 0) {
}

if ((Value & IsGraduate) != 0) {
}

// Set "Single"
Value |= IsSingle;

// Remove "Graduate"
Value &= ~IsGraduate;

答案 1 :(得分:11)

确实可以这样做,但不建议这样做。

如果您想在数据库中找到所有单身学生,该怎么办?还是男? 虽然您节省的空间很小,但您放弃了将数据编入索引的可能性,以便更快地搜索,但要查找具有取决于任何这些属性的查询条件的任何数据,您将需要执行位移操作在所有记录上(或检查多个整数值),这将最终变得非常慢。

在我看来,增加的复杂性并没有带来太多好处,数据库可以处理4个单独的字段,并且有充分的理由这样做(例如,轻松查询这些字段上的数据)。

答案 2 :(得分:10)

您可能会发现EnumSet是表示此信息的自然方式。 EnumSet在引擎盖下使用位掩码。

enum Interest {
   IsSingle,
   IsGraduate,
   IsMale,
   IsLookingForPartner 
}

EnumSet<Interest> interests = EnumSet.of(Interest.IsSingle, Interest.IsMale);

您可以添加任意数量的枚举值。

答案 3 :(得分:8)

使用二进制包装。为它们定义常量:

IsSingle = 1;
IsGraduate = 2;
IsMale = 4;
IsLookingForPartner = 8;

并将它们与逻辑OR运算结合起来。这样,每种可能性将由数字的二进制表示中的一位表示。您可以通过使用任何常量对打包值进行AND运算来检查:

short status = IsSingle | IsMale;    // will give 5

if ((status & IsMale) != 0)
    System.out.println("Male.");

答案 4 :(得分:3)

最好的是boolean[4],您可以将每个值保存在不同的数组单元格中,并且占用的空间最小!

在你的班级写下这段代码:

private boolean[] values = new boolean[4];

void setValue(String name, boolean value){
    if(name=="IsSingle")
        values[0] = value;
    else if(name=="IsGraduate")
        values[1] = value;
    else if(name=="IsMale")
        values[2] = value;
    else if(name=="IsLookingForPartner")
        values[3] = value;
}

boolean getValue(String name){
    if(name=="IsSingle")
        return values[0];
    else if(name=="IsGraduate")
        return values[1];
    else if(name=="IsMale")
        return values[2];
    else if(name=="IsLookingForPartner")
        return values[3];
    else
        return false;
}

现在只需使用:setValue("IsGraduate", true); getValue("IsMale");

答案 5 :(得分:3)

您是否考虑使用字节存储值?然后,您可以执行以下操作:

public Byte setDetails(bool isSingle, bool isGraduate, bool isMale, bool isLooking)
{
    Byte result = 0;

    //Set the details
    if (isSingle) result = result | 1;
    if (isGraduate) result = result | 2;
    if (isMale) result = result | 4;
    if (isLooking) result = result | 8;

    return result;
}

之后您可以使用以下代码:

Byte details = getDetails(true, false, true, false);
bool isSingle = (details & 1) != 0;

获取详细信息。

...那说,为了三个字节,是否值得所有额外的工作和常量?

答案 6 :(得分:3)

如果你想使用解决方案只是为了好玩,但如果这是专业应用程序,请不要在数据库中的单个参数中实现它。如果您这样做,请考虑业务的变化:

  1. 删除isLookingForPartner //冗余位将一直存在 - 顺序无关紧要
  2. 添加新参数
  3. 找到所有isLookingForPartner == true //将会很慢的人

答案 7 :(得分:0)

你真的应该使用单独的变量来存储它们。一个人可以是毕业生,单身男性,寻找伴侣。您根本无法将所有这些可能性存储在一个布尔值中。