핵심 정리

image.png

**// 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());
    }
}
**// Best Pattern**
// 코드 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());
    }
}

완벽 공략 48. bit array와 비트 연산자

bit vector, bimask, bitmap, bit set, bit string

• 비트 (0 또는 1) 구성된 배열. 예) 01011011,

• 비트 연산을 활용해 복잡한 로직을 효율적으로 계산할 수 있음.

• 비트 연산

• OR: 둘 중에 하나라도 1인 경우에 1, 아니면 0 => 해당 비트를 1로 설정. • AND: 둘 모두 1인 경우에만 1, 아니면 0 => 해당 비트를 0으로 설정. • XOR: 둘 중에 하나만 1인 경우에 1, 아니면 0 => 해당 비트를 반대값으로 설정. • NOT: 모든 비트를 반대로 변경

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();
    }
}

완벽 공략 49. EnumSet

Enum만 담을 수 있는 Set

• Enum을 일반 Set 구현체에 담아 사용하는 것보다 EnumSet에 담아 사용하는 것 이 효율적이다.

• 주요 기능

• allOf(Enum.class): 해당 Enum 타입의 모든 상수를 담은 EnumSet 만들기.

• noneOf(Enum.class): 비어있는 EnumSet 만들기.

• range(from, to): 개인적으로 사용을 권장하지 않음.

• contains, forEach, remove, …

public class EnumSetExample {

    public static void main(String[] args) {
        EnumSet<Text.Style> styles = EnumSet.of(Text.Style.BOLD, Text.Style.ITALIC);
				
				// EnumSet (o), EnumList(x)
        **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);

    }
}

==

// 코드 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());
    }
}