检查标志位的方法(Java)

52

我遇到了关于标志位的问题。 我有一个int变量用来保存标志。首先,我将一些标志设置为该变量。后来我需要检查在该变量中设置了多少个标志。但是我不知道该怎么做。

5个回答

91

检查一个位值是否被设置:

int value = VALUE_TO_CHECK | OTHER_VALUE_TO_CHECK;

if ((value & VALUE_TO_CHECK) == VALUE_TO_CHECK)
{
    // do something--it was set
}

if ((value & OTHER_VALUE_TO_CHECK) == OTHER_VALUE_TO_CHECK)
{
    // also set (if it gets in here, then it was defined in 
    //   value, but it does not guarantee that it was set with
    //   OR without other values. To guarantee it's only this
    //   value just use == without bitwise logic)
}

需要注意的是,除非0代表全部或没有选中(不要使用按位逻辑进行比较; 只需使用value == 0),否则不应将选中值设置为0,因为任何value & 0始终为0。


这里我没有标志(如VALUE_TO_CHECK)。我有另一个包含一些标志的变量。因此,我需要找出A是否包含B中存在的所有标志。 - Nagaraju
2
@Naga Raju,请澄清你的问题。 - user207421
1
如果你有一个值,其中设置了一堆标志:int A = flag1 | flag3 | flag15;,并且你想查看它是否具有来自 B 的所有值:int B = flag3 | flag15;,那么在上面的代码中,B 就是要检查的值:if (A & B == B)(忽略可怕的变量名)。此外,由于听起来你对此感到困惑,你应该参考 trashgod 的答案并购买所提及的书籍(作者为 Josh Bloch)。这是作为 Java 开发人员必备的最佳书籍。 - pickypg
1
你需要在内部再加一组括号才能编译通过,即如果 ((value & VALUE_TO_CHECK) == VALUE_TO_CHECK),并且对于 (value & OTHER_VALUE_TO_CHECK) 也是同样的情况。 - Cel
if 语句中下一行放大括号?发抖 :P - Jimbali
显示剩余2条评论

35

此外,考虑使用 EnumSet 代替位字段。另请参见 Bloch,第32项建议

补充说明:以具体的 示例 来说:

枚举集还为传统的比特标志提供了一个丰富的、类型安全的替代方案:

EnumSet.of(Style.BOLD, Style.ITALIC);

请注意特别方便的从AbstractSetAbstractCollection继承的方法。


我该如何使用它来替换位域?我无法做到这一点。 - Suragch
我不确定你遇到了什么问题;更多的例子可以在这里找到:http://stackoverflow.com/search?tab=votes&q=%5bjava%5d%20EnumSet%20bit%20field。 - trashgod

21

如果您想检查 a 是否拥有 b 中所有标志位设置,您可以这样检查:

(a & b) == b

10

我正在使用以下内容:

public class BitFlags
{
    public static boolean isFlagSet(byte value, byte flags)
    {
        return (flags & value) == value;
    }

    public static byte setFlag(byte value, byte flags)
    {
        return (byte) (flags | value);
    }

    public static byte unsetFlag(byte value, byte flags)
    {
        return (byte) (flags & ~value);
    }
}

然而,如果您不需要使用“低级别”的方式,则建议使用EnumSets,以获取类型安全的附加优势。


1
应该是 return (flags & value) == flags; 而不是 return (flags & value) == value;,对吗? - AndroidKotlinNoob

3

这是我在项目中使用的实用工具类

public class FlagUtils {

// ------------------------------------------------------------------------
// TYPES
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// STATIC FIELDS
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// STATIC METHODS
// ------------------------------------------------------------------------

/**
 * Sets the specified flags on the source int
 *
 * @param source the source int
 * @param flag   the flags which should be set
 *
 * @return the set int
 */
public static int setFlag(int source, int flag) {
    return source | flag;
}

/**
 * Un-sets the specified flags on the source int
 *
 * @param source the source int
 * @param flag   the flags which should be set
 *
 * @return the set int
 */
public static int unsetFlag(int source, int flag) {
    return source & ~flag;
}


/**
 * Check if the flags are set on the source ints
 *
 * @param source the source int
 * @param flag   the flags which should be set
 *
 * @return the set int
 */
public static boolean isFlagSet(int source, int flag) {
    return (source & flag) == flag;
}

/**
 * Flibs teh specified bit on the source
 *
 * @param source the source int
 * @param flag   the flags which should be set
 *
 * @return the set int
 */
public static int flip(int source, int flag) {
    return source & ~flag;
}

/**
 * Returns the masked int
 *
 * @param source the source int
 * @param mask
 *
 * @return the set int
 */
public static int mask(int source, int mask) {
    return source & mask;
}


// ------------------------------------------------------------------------
// FIELDS
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// CONSTRUCTORS
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// METHODS
// ------------------------------------------------------------------------

// ------------------------------------------------------------------------
// GETTERS / SETTTERS
// ------------------------------------------------------------------------

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接