Как переключить целочисленные флаги с помощью битового сдвига в Java?

У меня есть много объектов в матрице, которые хранят соединения со своими соседями в одной целочисленной переменной.

public static final int NONE = 0x00;
public static final int LEFT = 0x01;
public static final int TOP = 0x02;
public static final int RIGHT = 0x04;
public static final int BOTTOM = 0x08;

connections = LEFT | RIGHT | BOTTOM; // example usage

Теперь я хочу иметь возможность поворачивать определенные объекты на 90° по часовой стрелке или против часовой стрелки. В приведенном выше примере вращение по часовой стрелке должно быть эквивалентно

connections = TOP | BOTTOM | LEFT;

Битовый сдвиг влево/вправо, равный 1, кажется очевидным решением, но я не знаю, как ограничить битовый сдвиг битами от LEFT (0x01) до BOTTOM (0x08).

Я надеюсь, что кто-то может мне помочь. Я теряюсь, когда дело доходит до битовых операций.


person HD_92    schedule 15.10.2012    source источник
comment
По какой причине вы не хотите использовать вместо этого перечисление и EnumSet?   -  person Jon Skeet    schedule 15.10.2012
comment
Это из соображений производительности. Пишу игры для мобильных платформ.   -  person HD_92    schedule 15.10.2012
comment
Вы пытались использовать EnumSet и обнаружили, что это узкое место?   -  person Jon Skeet    schedule 15.10.2012
comment
Нет, прости. Я не знаю, есть ли большие улучшения производительности при использовании битового сдвига. Эта операция может выполняться очень часто во время игры для многих объектов (100+), поэтому казалось проще и быстрее просто использовать битовый сдвиг.   -  person HD_92    schedule 15.10.2012
comment
Никогда не гадать с производительностью. Напишите самый чистый код, который работает, проверьте его производительность и посмотрите, адекватен ли он. Если это не так, тогда оптимизируйте его до тех пор, пока он не станет адекватным.   -  person Jon Skeet    schedule 15.10.2012


Ответы (1)


Это должно сделать это:

connections = ((connections << 1) | (connections >> 3)) & 0x0f;
person fishinear    schedule 15.10.2012
comment
Благодарю вас! Это работает действительно здорово! Для вращения против часовой стрелки мне просто нужно было изменить левый сдвиг на правый сдвиг и наоборот! - person HD_92; 15.10.2012