How do you use bitwise operators to implement a set of boolean flags packed into a single int, and what operations set, clear, toggle, and test a flag?
answer
- flags = powers of two (1<<n)
- set |=, clear &=~, toggle ^=
- test (s & F) != 0
- all-of: (s & mask) == mask
- EnumSet for type-safe in-JVM flags
basics
~20 sGive each flag its own bit (1, 2, 4, 8...). Use | to turn a flag on, & with the mask to test it, &~ to turn it off, and ^ to flip it. One int can hold up to 32 flags.
solid answer
~50 sAssign each flag a distinct power-of-two constant so it occupies one bit position: `READ = 1`, `WRITE = 1 << 1`, `EXEC = 1 << 2`. Then on a state int: set with OR (`s |= WRITE`), clear with AND-NOT (`s &= ~WRITE`), toggle with XOR (`s ^= WRITE`), and test with AND against the mask (`(s & WRITE) != 0`). To test that all of several flags are present, AND with the combined mask and compare to the mask. An int packs 32 flags, a long 64. This is compact and fast — a single machine word, branch-free updates — and is how OS permission bits, regex flags, and event masks are built. The modern Java alternative when you don't need raw ints is `EnumSet`, which is type-safe and just as efficient (it's backed by a bitfield), so prefer it unless you must interoperate with a numeric protocol.
code
java · 14 linesstatic final int READ = 1, WRITE = 1 << 1, EXEC = 1 << 2;
int s = 0;
s |= READ | WRITE; // set READ and WRITE
boolean canWrite = (s & WRITE) != 0; // test -> true
boolean canExec = (s & EXEC) != 0; // test -> false
s &= ~WRITE; // clear WRITE
s ^= EXEC; // toggle EXEC on
int rw = READ | WRITE;
boolean hasBoth = (s & rw) == rw; // all-of test
// modern, type-safe alternative:
// EnumSet<Perm> perms = EnumSet.of(Perm.READ, Perm.WRITE);go deeper
Can turn a flag on with | and test it with &, given the constants.
Implements set/clear/toggle/test correctly, defines flags as powers of two, and tests all-of with == mask.
Knows the sign-bit/long tradeoff, the comparison pitfalls, and recommends EnumSet for type-safe in-JVM use while keeping masks for protocols.
Designs flag/permission APIs, weighs bitmask vs EnumSet vs separate fields for clarity, evolvability, and interop, and sets team conventions.
## The idea: one bit per yes/no A single `int` is 32 bits. If each bit means 'is this one option on?', a single int can store the on/off state of up to 32 independent options. This is a **bit field** or **flag set**. ## Define flags as powers of two Each flag must occupy a *different* bit, so each constant is a distinct power of two: ``` static final int READ = 1; // 0001 static final int WRITE = 1 << 1; // 0010 static final int EXEC = 1 << 2; // 0100 ``` Using `1 << n` makes the bit position obvious and avoids typos. Never reuse a value. ## The four core operations Let `s` be the current state int and `F` a flag mask. - **Set (turn on):** `s |= F;` — OR forces that bit to 1 and leaves the others untouched. - **Clear (turn off):** `s &= ~F;` — `~F` is all 1s except F's bit; ANDing zeroes only F's bit. - **Toggle (flip):** `s ^= F;` — XOR flips F's bit, leaving others alone. - **Test (is it on?):** `(s & F) != 0` — AND isolates F's bit; non-zero means it was set. ## Combining and testing multiple flags Combine masks with OR: `int rw = READ | WRITE;`. - 'Has *any* of these?': `(s & rw) != 0`. - 'Has *all* of these?': `(s & rw) == rw`. ## Why bother — pros - **Compact**: 32 booleans in 4 bytes instead of 32 bytes. - **Fast**: set/clear/test are single CPU instructions, no branching. - **Atomic-ish grouping**: pass one int through an API instead of many parameters. ## Pitfalls - **Test mistake**: `if (s & F)` does not compile in Java (the result is an int, not a boolean) and writing `if ((s & F) == 1)` is wrong unless F == 1; always compare `!= 0` or `== F`. - **Sign bit**: bit 31 is the sign bit; a flag there makes the int negative, which is fine for masks but surprises printing. Use `long` if you need bit 63 cleanly or more than 31 comfortable flags. - **Magic numbers**: always name the constants. ## The modern alternative: EnumSet Java's `java.util.EnumSet` gives the same packed-bitfield performance with type safety and readable code (`EnumSet.of(Perm.READ, Perm.WRITE)`), and supports `contains`, `add`, `remove`. Prefer it for in-JVM flag sets; reserve raw int masks for numeric wire/file/OS protocols where the exact bits matter.
- Why use &= ~F to clear a flag rather than s -= F?Subtraction only works if the flag is currently set and corrupts the value if it isn't (or if other bits interact). &= ~F always clears exactly that bit regardless of current state.
- When should you prefer EnumSet over an int bitmask?Almost always for in-JVM code: EnumSet is type-safe, readable, and equally fast (bitfield-backed). Use raw int masks only to match an external numeric protocol or persisted format.
saying these in an interview costs you the question
- Comparing (s & F) == 1 instead of != 0
- Assigning non-power-of-two values to flags (bits overlap)
- Forgetting ~ when clearing (using &= F clears everything else)
- Claiming an int can hold 32 flags 'except the sign bit makes it 31' as if bit 31 is unusable (it works as a mask, just prints negative)