Enum 클래스를 작성하다 보면 그룹화가 필요할 때가 있다.
나 같은 경우는 city와 country가 이러한 경우였다.
@ToString
@AllArgsConstructor
public enum CityEnum implements CodeEnumExt{
SEOUL("1",CountryEnum.KOREA,"서울"),
BUSAN("2",CountryEnum.KOREA, "부산"),
CEBU("3",CountryEnum.PHILIPPINES, "세부"),
MANILA("4",CountryEnum.PHILIPPINES, "마닐라"),
BORACAY("5",CountryEnum.PHILIPPINES, "보라카이"),
DANANG("6",CountryEnum.VIETNAM, "다낭"),
HOCHIMINH("7",CountryEnum.VIETNAM, "호치민"),
NHATRANG("8",CountryEnum.VIETNAM, "나트랑"),
BOHOL("9",CountryEnum.PHILIPPINES, "보홀");
private final String code;
private final CountryEnum parentCode;
private final String comment;
}
@ToString
@AllArgsConstructor
public enum CountryEnum implements CodeEnum {
KOREA("1", "한국"),
PHILIPPINES("2", "필리핀"),
VIETNAM("3", "베트남");
private final String code;
private final String comment;
@Override
public String getComment() {
return comment;
}
@Override
public String getKey() {
return name();
}
@Override
public String getCode() {
return code;
}
}
CityEnum 값들은 CountryEnum으로 정의된 parentCode을 갖고 해당 도시가 어느 나라에 속하는지 보여준다.
해당 Enum을 계속 사용하다 보니
자식 Enum 코드가 어느 부모에 값에 속하는지 +
부모 코드의 값은 어떤 것들이 있는지 가 필요해졌다.
ex) 대한민국의 도시 -> 서울,부산
필리핀의 도시 -> 마닐라, 세부 ..
하여, 다시 한 번 갓동욱님의 힘을 빌어 Enum 그룹화에 응용해보았다.
참조링크
(https://github.com/jojoldu/blog-code/tree/master/java/enum-mapper)
public interface CodeEnum {
public String getCode();
public String getKey();
public String getComment();
}
public interface CodeEnumExt extends CodeEnum{
public <T extends Enum<T> & CodeEnum> T getParentCode();
}
내 프로젝트 내에 선언된 모든 Enum 클래스는 CodeEnum 인터페이스를 구현한다.
이에 CodeEnumExt를 만들어 CodeEnum을 부모로 갖는 Enum 클래스를 지정
하였다.
public class EnumGroup {
public static <T extends Enum<T> & CodeEnumExt, E extends Enum<E> & CodeEnum> List<T> getEnumByGroup(Class<T> enumClass, E parentCode){
return EnumSet.allOf(enumClass)
.stream()
.filter(type -> type.getParentCode().equals(parentCode))
.collect(Collectors.toList());
};
public static <E extends Enum<E> & CodeEnum> List<E> getParentEnum(Class<E> enumClass){
return EnumSet.allOf(enumClass)
.stream()
.collect(Collectors.toList());
};
}
getEnumByGroup은 파라미터로 받은 부모코드에 해당하는 EnumSet을 List형태로 반환한다.
getParentEnum은 말 그대로 부모 EnumSet을 List로 반환한다.
@ToString
@AllArgsConstructor
public enum CityEnum implements CodeEnumExt{
SEOUL("1",CountryEnum.KOREA,"서울"),
BUSAN("2",CountryEnum.KOREA, "부산"),
CEBU("3",CountryEnum.PHILIPPINES, "세부"),
MANILA("4",CountryEnum.PHILIPPINES, "마닐라"),
BORACAY("5",CountryEnum.PHILIPPINES, "보라카이"),
DANANG("6",CountryEnum.VIETNAM, "다낭"),
HOCHIMINH("7",CountryEnum.VIETNAM, "호치민"),
NHATRANG("8",CountryEnum.VIETNAM, "나트랑"),
BOHOL("9",CountryEnum.PHILIPPINES, "보홀");
private final String code;
private final CountryEnum parentCode;
private final String comment;
@Override
public String getComment() {
return comment;
}
@Override
public String getKey() {
return name();
}
@Override
public String getCode() {
return code;
}
@Override
public CountryEnum getParentCode() {
return parentCode;
}
public static List<CityEnum> getEnumByGroup(CountryEnum parentCode){
return EnumGroup.getEnumByGroup(CityEnum.class, parentCode);
}
public static List<CountryEnum> getParentEnum(){
return EnumGroup.getParentEnum(CountryEnum.class);
}
}
부모 코드를 가진 enum(implement CodeEnumExt)에
EnumGroup에서 정의한 메소드를 입력한다.
@Test
public void testEnumGroupCity() {
List<CityEnum> list = CityEnum.getEnumByGroup(CountryEnum.KOREA);
list.stream()
.forEach(x -> System.out.println("groupEnum : " + x));
}
@Test
public void testParentEnumCity() {
CityEnum.getParentEnum().stream()
.forEach(x -> System.out.println("parentEnum : " + x));
}
getParentEnum()를 사용해
필요한 부모 enumSet을 알아내고 각각의 자식 enum그룹을 getEnumByGroup()로 추출 해낼 수 있다.