[Java] Enum values 조회 (Baeldung)공부/Java2023. 7. 26. 13:59
Table of Contents
반응형
1. Enum Month 클래스 생성
- 각 Month 인스턴스는 code와 number 값을 가짐
- Enum Constructor(생성자)는 기본적으로 private 로 생략가능하다.
public enum Month {
JANUARY("Jan", 1),
FEBRUARY("Feb", 2),
MARCH("Mar", 3),
APRIL("Apr", 4),
MAY("May", 5),
JUNE("Jun", 6),
JULY("Jul", 7),
AUGUST("Aug", 7),
SEPTEMBER("Sept", 7),
OCTOBER("Oct", 10),
NOVEMBER("Nov", 11),
DECEMBER("Dec", 12);
private final String code;
private final int number;
Month(String code, int number) {
this.code = code;
this.number = number;
}
public String getCode() {
return code;
}
public int getNumber() {
return number;
}
}
참고.
enum은 각각 자기자신을 인스턴스화한 객체를 가지게 되는데, 아래와 같이 정적인 상수 클래스가 선언 되었다고 이해할 수 있다
public enum Month {
public static final Month JANUARY = new Month("Jan", 1);
// ...
public static final Month DECEMBER = new Month("Dec", 2);
private final String code;
private final int number;
Month(String code, int number) {
this.code = code;
this.number = number;
}
public String getCode() {
return code;
}
public int getNumber() {
return number;
}
}
자바 컴파일을 해보게 되면 아래와 같은 형태로 확인된다
$ javac Month.java
$ javap Month.class
public final class {패캐지경로}.Month extends java.lang.Enum<{패키지경로}.Month> {
public static final {패키지경로}.Month JANUARY;
public static final {패키지경로}.Month FEBRUARY;
public static final {패키지경로}.Month MARCH;
public static final {패키지경로}.Month APRIL;
public static final {패키지경로}.Month MAY;
public static final {패키지경로}.Month JUNE;
public static final {패키지경로}.Month JULY;
public static final {패키지경로}.Month AUGUST;
public static final {패키지경로}.Month SEPTEMBER;
public static final {패키지경로}.Month OCTOBER;
public static final {패키지경로}.Month NOVEMBER;
public static final {패키지경로}.Month DECEMBER;
public static basic.function.Month[] values();
public static basic.function.Month valueOf(java.lang.String);
public java.lang.String getCode();
public int getNumber();
static {};
}
2. name() 활용하여 Enum 찾기
- Enum 추상 클래스 통해 name() method가 기본적으로 제공된다
- Enum 클래스에서 선언한 열거 객체의 명칭을 문자열로 반환
- Java 버전이 지원할 경우 현대적인 stream API 사용 권장
2-1. forEach 활용
static Month[] values() {
return Month.values();
}
static Month findByName(String name) {
Month result = null;
for(Month m : values()) {
if(m.name().equalsIgnoreCase(name)) { // equalsIgnoreCase (String.class)
return = m;
break;
}
}
return result;
}
@DisplayName("올바른 name을 인자로 전달할 때, findByName 통해 Month 상수 객체가 반환된다")
@Test
void whenValidDirectionNameProvided_thenDirectionIsFound() {
// given
String givenName = "december";
// when
Direction result = findByName(givenName);
// then
Assertions.assertThat(result).isEqualTo(Month.DECEMBER); // OK
}
2-2. stream API 활용
조회시 filter에 해당하는 첫 값을 리턴하고 없으면 IllegalArgumentException 을 던진다
static Month[] values() {
return Month.values();
}
static Month findByName(String name) {
return Arrays.stream(values()).filter(month -> month.name().equalsIgnoreCase(name))
.findFirst().orElseThrow(IllegalArgumentException::new);
}
@DisplayName("올바른 name을 인자로 전달할 때, findByName 통해 Month 상수 객체가 반환된다")
@Test
void whenValidDirectionNameProvided_thenDirectionIsFound() {
// given
String givenName = "December";
// when
Direction result = findByName(givenName);
// then
Assertions.assertThat(result).isEqualTo(Month.DECEMBER); // OK
}
@DisplayName("틀린 name이 인자로 주어졌을 때, findByname 실행시 IllegalArgumentException 예외를 던진다")
@Test
void findByNameException() {
// given
String givenName = "holiday";
// when
// then
Assertions.assertThatThrownBy(() -> findByName(givenName))
.isInstanceOf(IllegalArgumentException.class); // Ok
}
- equalsIgnoreCase() : 대소문자 구분 x
3. 직접 선언한 String 필드 사용 (String code)하여 Enum 찾기
- name()의 경우 추상클래스 enum에 선언되었지만, 사용자 정의 필드의 경우 getter method를 생성해서 사용
- 내용은 name()과 동일
- Java 버전이 지원할 경우 현대적인 stream API 사용 권장
3-1. forEach 활용
static Month findByCode(String code) {
Month month = null;
for(Month m : values()) {
if(m.getCode().equalsIgnoreCase(code)) {
month = m;
break;
}
}
return month;
}
@DisplayName("code 값이 존재하는 경우 Month 객체 반환를 반환한다")
@Test
void searchByCode() {
// given
String givenCode = "nov";
// when
Month result = findByCode(givenCode);
// then
assertThat(result).isEqualTo(Month.NOVEMBER); // Ok
}
3-2. stream API 활용
static Month findByCode(String code) {
return Arrays.stream(values())
.filter(month -> month.getCode().equalsIgnoreCase(code))
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
@DisplayName("code 값이 존재하는 경우 Month 객체 반환를 반환한다")
@Test
void searchByCode() {
// given
String givenCode = "nov";
// when
Month result = findByCode(givenCode);
// then
assertThat(result).isEqualTo(Month.NOVEMBER); // Ok
}
@DisplayName("없는 Month 코드 조회할 경우, findByCode 실행시 IllegalArgumentException 던진다")
@Test
void givenMonthCode_whenCodeNotFound_thenThrowIllegalArgumentException() {
// given
String givenEmptyCode = "empty";
// when
// then
assertThatThrownBy(() -> findByCode(givenEmptyCode))
.isInstanceOf(IllegalArgumentException.class); // Ok
}
4. 직접 선언한 int 필드 사용(int number)하여 Enum 찾기
- 위와 동일하고 primitive type 사용하기 때문에 filter/조건문에서 비교 연산자로 대체됨
4-1. forEach 활용
static Month findByNumber(int monthNumber) {
Month result = null;
for(Month m : values()) {
if(m.getNumber() == monthNumber) {
result = m;
break;
}
}
return result;
}
@DisplayName("number 값이 존재하는 경우, findByNumber 실행시 Month 객체 반환를 반환한다")
@Test
void searchByNumber() {
// given
int givenMonthNumber = 12;
// when
Month result = findByNumber(givenMonthNumber);
// then
assertThat(result).isEqualTo(Month.DECEMBER);
}
4-2. stream API 활용
static Month findByNumber(int monthNumber) {
return Arrays.stream(values()).filter(month -> month.getNumber() == monthNumber).findFirst()
.orElseThrow(IllegalArgumentException::new);
}
@DisplayName("number 값이 존재하는 경우 Month 객체 반환를 반환한다")
@Test
void searchByNumber() {
// given
int givenMonthNumber = 12;
// when
Month result = findByNumber(givenMonthNumber);
// then
assertThat(result).isEqualTo(Month.DECEMBER);
}
@DisplayName("없는 number 의 경우, findByNumber 실행시 IllegalArgumentException 던진다")
@Test
void givenMonthNumber_whenCodeNotFound_thenThrowIllegalArgumentException() {
// given
int givenEmptyMonthNumber = 13;
// when
// then
assertThatThrownBy(() -> findByNumber(givenEmptyMonthNumber))
.isInstanceOf(IllegalArgumentException.class);
}
참고 & 출처
반응형
'공부 > Java' 카테고리의 다른 글
[Java] FunctionalInterface와 Lambda Expression (0) | 2023.07.28 |
---|---|
[Java] Enum (이펙티브 자바 3판) (0) | 2023.07.26 |
[Java] Enum values 배열을 리스트 변환 (Baeldung, Enum values to List) (0) | 2023.07.21 |
[Java] Generics (제네릭) - 공변/무공변/반공변, PECS (0) | 2023.07.21 |
[Java] Annotation - 어노테이션 (자바의 정석) (0) | 2023.07.19 |
@leejinwoo1126 :: 천천히 하나씩
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!