【发布时间】:2011-05-20 04:17:40
【问题描述】:
我对标志位有疑问。
我有一个 int 变量来保存标志。首先,我为该变量设置了一些标志。稍后我需要检查在该变量中设置了多少标志。但我不知道该怎么做。
【问题讨论】:
标签: java bit-manipulation flags
我对标志位有疑问。
我有一个 int 变量来保存标志。首先,我为该变量设置了一些标志。稍后我需要检查在该变量中设置了多少标志。但我不知道该怎么做。
【问题讨论】:
标签: java bit-manipulation flags
这是我在项目中使用的实用程序类
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
// ------------------------------------------------------------------------
}
【讨论】:
检查是否设置了位值:
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,除非它表示 All 或 None(并且不要使用按位逻辑进行比较;只需使用 value == 0),因为任何 value & 0 始终为 0。
【讨论】:
int A = flag1 | flag3 | flag15;,并且你想看看它是否包含来自B的所有值:int B = flag3 | flag15;,然后B 是VALUE_TO_CHECK在上面的代码中:if (A & B == B)(忽略可怕的变量名)。另外,由于听起来您对此感到困惑,因此您应该参考垃圾神的答案并购买参考书(乔什·布洛赫(Josh Bloch)撰写)。作为 Java 开发人员,这是一本最好的书。
if 语句下一行的大括号? 颤抖 :P
如果要检查a是否设置了b中的所有标志位,可以检查为:
(a & b) == b
【讨论】:
我正在使用以下内容:
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 来代替类型安全的额外好处。
【讨论】:
return (flags & value) == flags;而不是return (flags & value) == value;吗?
另外,考虑使用EnumSet 代替位字段。另见Bloch, Item 32。
附录:具体example:
枚举集还为传统的位标志提供了丰富的类型安全替代:
EnumSet.of(Style.BOLD, Style.ITALIC);
特别注意从AbstractSet 和AbstractCollection 继承的便捷方法。
【讨论】: