Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions core.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,119 @@ short s = 7; // 0000 0000 0000 0111

[к оглавлению](#java-core)

## Как применяют побитовые операции?

+ Маски (битовые флаги)
+
Маска — это число, в котором каждый бит используется как отдельный флаг (true/false). Это позволяет хранить несколько булевых значений в одной переменной int или long.

`
final int READ = 1 << 0; // 0001 = 1
final int WRITE = 1 << 1; // 0010 = 2
final int EXECUTE = 1 << 2; // 0100 = 4

int rights = READ | WRITE; // 0011 = 3 (чтение + запись)

// Проверка
boolean canRead = (rights & READ) != 0; // true
boolean canExecute = (rights & EXECUTE) != 0; // false

// Добавим EXECUTE
rights |= EXECUTE; // теперь 0111 = 7

// Уберём WRITE
rights &= ~WRITE; // теперь 0101 = 5 (READ + EXECUTE)
`

Здесь | используется для добавления флага,
& для проверки,
~ для обнуления конкретного бита.

В Java часто вместо масок используют EnumSet, но маски полезны, если надо хранить очень много флагов компактно (например, при работе с сетью или драйверами).

`
enum Permission {
READ(1 << 0),
WRITE(1 << 1),
EXECUTE(1 << 2);

final int mask;
Permission(int mask) { this.mask = mask; }
}

`
+ Быстрое умножение/деление на степени двойки

Сдвиги влево и вправо работают быстрее, чем умножение/деление.

`
int x = 5 << 1; // 10 (5 * 2)
int y = 20 >> 2; // 5 (20 / 4)

int z = 7;

int mul = z << 1; // 14 (7 * 2)
int div = z >> 1; // 3 (7 / 2)
`

+ Оптимизация в алгоритмах
__Проверка чётности__
`
int n = 10;
if ((n & 1) == 0) {
System.out.println("Чётное");
} else {
System.out.println("Нечётное");
}
`
__Быстрый модуль по степени двойки__
`
int n = 77;
int mod = n & (8 - 1); // 77 % 8 = 5
System.out.println(mod); // 5
`

__Переключение флага (toggle)__
`
int flags = 0;

// переключаем WRITE
flags ^= WRITE; // включили WRITE
flags ^= WRITE; // снова выключили WRITE

`
__Очистка всех флагов, кроме одного__
`
int flags = READ | WRITE | EXECUTE;
flags &= READ; // оставляем только READ
`

__Интересные применения__

Хранение состояний: например, в графике (VISIBLE, ENABLED, SELECTED).

Комбинация параметров: настройки работы функции (FULLSCREEN | VSYNC).

Быстрая работа с большими массивами булевых значений (экономия памяти).

[к оглавлению](#java-core)

## Разница >> и >>>

>>> и <<< сдвиги без учета знака
`
int x = -8; // 11111111111111111111111111111000

System.out.println(x >> 2); // -2 (111111...1110) — арифметический сдвиг
System.out.println(x >>> 2); // 1073741822 (001111...1110) — логический сдвиг

`
Зачем нужен >>>, если есть >>?

Ответ: для работы с int/long как беззнаковыми числами (например, при работе с сетевыми протоколами или бинарными файлами).

[к оглавлению](#java-core)

## Autoboxing и unboxing?
__Автоупаковка__ - автоматическая инкапсуляция примитивного типа в эквивалентную ему класс-обёртку всякий раз, когда требуется объект данного типа.

Expand Down