Bitmask – способ хранить несколько булевых параметров в одном числе. Каждый параметр занимает один бит: 1, 2, 4, 8, 16, 32 и так дальше. Если нужно включить сразу несколько параметров, их значения объединяются побитовым or. Такой подход удобен, когда с сервера приходит компактное поле Int, но в приложении хочется работать не с магическими числами, а с понятными enum-значениями. Например, у пользователя может быть несколько бейджей: verified, new, star, crown. Вместо массива строк сервер может вернуть одно число:
enum class BadgeEnum(
val bit: Int
) {
BADGE_EMPTY(0), // 0
BADGE_VERIFIED(1 shl 0), // 1
BADGE_OLD(1 shl 1), // 2
BADGE_NEW(1 shl 2), // 4
BADGE_STAR(1 shl 3), // 8
BADGE_CROWN(1 shl 4), // 16
BADGE_HEART(1 shl 5), // 32
BADGE_RICH(1 shl 6); // 64
}
{
"name": "Jane Yang",
"badges": 125
}
125 – это не случайное значение. Это сумма включенных битов: 125 = 1 + 4 + 8 + 16 + 32 + 64. Значит у пользователя включены флаги VERIFIED, NEW, STAR, CROWN, HEART, RICH, но не включен OLD, потому что бит 2 в числе отсутствует.
Bitmask хорошо подходит для набора независимых флагов, которые могут быть включены одновременно:
Bitmask не нужен, если значение может быть только одно. Для такого сценария достаточно обычного enum class. Например, статус заказа NEW, PAID, CANCELLED – это не bitmask, потому что заказ не должен быть одновременно новым и отмененным.
Каждый флаг получает значение через сдвиг 1 shl n:
1 shl 0 // 1
1 shl 1 // 2
1 shl 2 // 4
1 shl 3 // 8
1 shl 4 // 16
Это степени двойки. У каждой степени двойки включен только один бит, поэтому значения не пересекаются между собой.