Enum 정리
Enum 정리
Basic
non-enum
1
2
3
4
5
class State {
public static final State READY = new STATE();
public static final State PLAY = new STATE();
public static final State EXIT = new STATE();
}
enum
1
2
3
enum State {
READY, PLAY, EXIT
}
1. 코드성 엔터티
1
2
3
public enum AttachmentGroupRole {
PROFILE, BOARD
}
1
2
3
public enum BoardType {
A,B,C
}
1
2
3
public enum BoardCommentStatus {
AVAILABLE, DELETED
}
1
2
3
public enum UserRole {
USER, ADMIN
}
프로젝트 할 때 코드성 엔터티를 DB로 안빼고 Application 단에서 처리했었음
2. 싱글톤 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 열거 타입 방식의 싱글턴 - 바람직한 방법 (이펙티브자바 3E :25p)
enum Elvis {
INSTANCE;
public void leaveTheBuilding() {
System.out.println("기다려 자기야, 지금 나갈께!");
}
}
public Main {
public static void main(String[] args) {
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBuilding();
}
}
- 직렬화, 리플렉션 에도 싱글톤 유지함.
- static final / static method 로 싱글톤을 구현하는 경우는
- 직렬화를 위해 추가적인 작업 필요
- 리플렉션으로 객체 생성 가능해서 의도적으로 싱글톤을 무너트릴 수 있음.
- static final / static method 로 싱글톤을 구현하는 경우는
근데 이거 쓰는거 본적이 없는데..
3. 데이터 그룹 관리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public enum BoardGroup {
ADMIN("관리자", Arrays.asList("안되", "오지마")),
USER("유저", Arrays.asList("자유게시판", "구루구구")),
EMPTY("없음", Collections.emptyList());
private String title;
private List<String> boards;
private BoardGroup(String title, List<String> boards) {
this.title = title;
this.boards = boards;
}
public static BoardGroup findByBoardCode(String boardCode) {
return Arrays.stream(BoardGroup.values())
.filter(boardGroup -> boardGroup.hasBoard(boardCode))
.findAny()
.orElse(EMPTY);
}
private boolean hasBoard(String boardCode) {
return boards.stream()
.anyMatch(board -> board.equals(boardCode));
}
}
이동욱님의 글을 참고 함. http://woowabros.github.io/tools/2017/07/10/java-enum-uses.html
4. 익명 메소드
사칙연산을 수행하는 Operation을 만들 수 있따.
익명메서드를 선언하고, 구현은 위에서 해버리기.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 이펙티브자바 <Item 34>
enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
public abstract double apply(double x, double y);
Operation(String symbol) {
this.symbol = symbol;
}
@Override
public String toString() {
return symbol;
}
}
public class AbstractMethod {
public static void main(String[] args) {
double x = 1.1;
double y = 3.3;
for (Operation op : Operation.values())
System.out.printf("%f %s %f = %f%n",
x, op, y, op.apply(x, y));
// 1.100000 + 3.300000 = 4.400000
// 1.100000 - 3.300000 = -2.200000
// 1.100000 * 3.300000 = 3.630000
// 1.100000 / 3.300000 = 0.333333
}
}
5. Functional Interface
위의 익명 메서드 대신 Functional Interface를 사용하여 사칙연산을 구현할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 이펙티브자바 <Item 42>
public enum Operation {
PLUS("+", (x, y) -> x + y),
MINUS("-", (x, y) -> x - y),
TIMES("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
@Override
public String toString() { return symbol; }
}
우테코 프리코스 과제 (숫자 야구게임)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public enum State {
PLAY_CONTINUE(Constant.PLAY_CONTINUE_NUMBER),
EXIT(Constant.EXIT_GAME_NUMBER);
private final int value;
private State(int value) {
this.value = value;
}
public static State findState(int i) {
return Arrays.stream(State.values())
.filter(x -> x.getValue() == i)
.findAny()
.orElseThrow(() -> new IllegalArgumentException("잘못된 입력 값 입니다. :: " + i));
}
public int getValue() {
return value;
}
}
우테코 프리코스 과제 (로또)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public enum Rank {
FIRST(6, 2_000_000_000), // 1등
SECOND(5, 30_000_000), // 2등
THIRD(5, 1_500_000), // 3등
FOURTH(4, 50_000), // 4등
FIFTH(3, 5_000), // 5등
MISS(0, 0);
private static final int WINNING_MIN_COUNT = 3;
private final int countOfMatch;
private final int winningMoney;
private Rank(int countOfMatch, int winningMoney) {
this.countOfMatch = countOfMatch;
this.winningMoney = winningMoney;
}
public int getCountOfMatch() {
return countOfMatch;
}
public int getWinningMoney() {
return winningMoney;
}
public static Rank valueOf(int countOfMatch, boolean matchBonus) {
if (countOfMatch < WINNING_MIN_COUNT) {
return MISS;
}
if (SECOND.matchCount(countOfMatch) && matchBonus) {
return SECOND;
}
for (Rank rank : values()) {
if (rank.matchCount(countOfMatch) && rank != SECOND) {
return rank;
}
}
throw new IllegalArgumentException(countOfMatch + "는 유효하지 않은 값입니다.");
}
private boolean matchCount(int countOfMatch) {
return this.countOfMatch == countOfMatch;
}
}
이 기사는 저작권자의
CC BY 4.0
라이센스를 따릅니다.