
package me.whiteship.chapter06.item36.anti_pattern;
public class Text {
public static final int STYLE_BOLD = 1 << 0; // 00000001 1 굵게
public static final int STYLE_ITALIC = 1 << 1; // 00000010 2 이탤릭체
public static final int STYLE_UNDERLINE = 1 << 2; // 00000100 4 밑줄
public static final int STYLE_STRIKETHROUGH = 1 << 3; // 00001000 8 취소선
private int currentStyle;
public void applyStyles(int styles) {
System.out.printf("Applying styles %s to text%n", styles);
this.currentStyle = styles;
}
public boolean isBold() {
// TODO 00000011
// TODO & 00000001
// TODO 00000001
return (currentStyle & STYLE_BOLD) == STYLE_BOLD;
}
public boolean isItalic() {
return (currentStyle & STYLE_ITALIC) == STYLE_ITALIC;
}
public static void main(String[] args) {
Text text = new Text();
// TODO 00000001
// TODO | 00000010
// TODO 00000011
text.applyStyles(STYLE_BOLD | STYLE_ITALIC);
System.out.println(text.isBold());
}
}
낯선 코딩 기법이고 실수할 수 있다.

package me.whiteship.chapter06.item36.best_practice;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
// 코드 36-2 EnumSet - 비트 필드를 대체하는 현대적 기법 (224쪽)
public class Text {
public enum Style {BOLD, ITALIC, UNDERLINE, STRIKETHROUGH}
private Set<Style> styles;
// 어떤 Set을 넘겨도 되나, EnumSet이 가장 좋다.
public void applyStyles(Set<Style> styles) {
System.out.printf("Applying styles %s to text%n",
Objects.requireNonNull(styles));
this.styles = EnumSet.copyOf(styles);
}
public boolean isBold() {
return styles.contains(Style.BOLD);
}
public boolean isItalic() {
return styles.contains(Style.ITALIC);
}
// 사용 예
public static void main(String[] args) {
Text text = new Text();
text.applyStyles(EnumSet.of(Style.BOLD, Style.ITALIC));
System.out.println(text.isBold());
}
}


package me.whiteship.chapter06.item36.bit_array;
public class BitOperation {
private final int one = 1;
private final int two = 1 << 1;
private final int four = 1 << 2;
private final int eight = 1 << 3;
public static void main(String[] args) {
BitOperation bitOperation = new BitOperation();
printBits(bitOperation.one);
printBits(bitOperation.two);
printBits(bitOperation.four);
printBits(bitOperation.eight);
int three = bitOperation.one | bitOperation.two;
printBits(three);
printBits(bitOperation.one);
// printBits(three & bitOperation.one);
// printBits(three & bitOperation.two);
// printBits(three & bitOperation.four);
printBits(three ^ bitOperation.one);
printBits(~three);
}
private static void printBits(int i) {
for (int j = 31; j >= 0; j--) {
System.out.print((i & (1 << j)) == 0 ? 0 : 1);
}
System.out.println();
}
}

|은 추가가 되는 것이다.


&연산은 각각 자기 자신이 나오게 되어있다. &연산은 뭔가를 담고 있는지 확인 할 때 주로 사용을 한다.


XOR은 같은 자리가 1과 0 일 때 1이다.

NOT은 비트를 반대로 뒤집어준다.

package me.whiteship.chapter06.item36.enum_set;
import me.whiteship.chapter06.item36.best_practice.Text;
import java.util.EnumSet;
public class EnumSetExample {
public static void main(String[] args) {
EnumSet<Text.Style> styles = EnumSet.of(Text.Style.BOLD, Text.Style.ITALIC);
Text.Style[] values = Text.Style.values();
EnumSet<Text.Style> styles1 = EnumSet.allOf(Text.Style.class);
System.out.println(styles1);
EnumSet<Text.Style> styles2 = EnumSet.noneOf(Text.Style.class);
System.out.println(styles2);
EnumSet<Text.Style> styles3 = EnumSet.range(Text.Style.BOLD, Text.Style.UNDERLINE);
System.out.println(styles3);
System.out.println(styles3.contains(Text.Style.BOLD));
styles3.forEach(System.out::println);
EnumSet<Text.Style> styles4 = EnumSet.complementOf(styles3);
System.out.println(styles4);
boolean remove = styles3.remove(Text.Style.BOLD);
System.out.println(styles3);
}
}
allOf는 모든 걸 담아준다.
noneOf는 비어있는 EnumSet을 만들어준다.
range는 사용을 권하지는 않지만, 정해진 순서에 따라가기 때문이다. 정해진 순서가 바뀌기 때문이다. Ordinal에 기반한것은 전부 안 좋다.
complementOf는 NOT이다. 안에 들어간 것 빼고 다 넣어준다는 뜻이다.(Style3가 Text.Style을 참조하기 때문에 같이 참조할 수 있는 것 같다.)
