У меня проблема с битами флага. У меня есть переменная int
для хранения флагов. Сначала я установил несколько флагов для этой переменной. Позже мне нужно проверить, сколько флагов было установлено в этой переменной. Но я не знаю, как это сделать.
Проверка битов флага java
Ответы (5)
Чтобы проверить, установлено ли значение бита:
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)
(игнорируя ужасные имена переменных). Кроме того, поскольку это звучит так, как будто вас это смущает, вам следует сослаться на ответ TrashGod и купить книгу, на которую ссылаются (Джоша Блоха). Это лучшая книга для Java-разработчика.
- person pickypg; 20.05.2011
if
? вздрагивает :P
- person Jimbali; 24.12.2014
Кроме того, рассмотрите возможность использования EnumSet
вместо битового поля. См. также Блох, пункт 32.
Приложение: В качестве конкретного примера:
Наборы Enum также обеспечивают богатую, безопасную замену традиционных битовых флагов:
EnumSet.of(Style.BOLD, Style.ITALIC);
Обратите особое внимание на удобные методы, унаследованные от AbstractSet
и AbstractCollection
.
Если вы хотите проверить, установлены ли все флаговые биты 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;
?
- person AndroidKotlinNoob; 28.06.2021
Вот мой служебный класс, который я использую в своих проектах.
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
// ------------------------------------------------------------------------
}