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 хорошо подходит для набора независимых флагов, которые могут быть включены одновременно:

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

Это степени двойки. У каждой степени двойки включен только один бит, поэтому значения не пересекаются между собой.