티스토리 뷰
EnumSet을 사용하는 방법
EnumSet은 다른 컬렉션들과 다르게 new 연산자 사용이 불가능합니다. EnumSet은 아래와 같은 방법으로 사용합니다.
//DayOfWeek라는 Enum을 다루는 Set으로 비어있는 Set을 반환
EnumSet enumSet1 = EnumSet.noneOf(DayOfWeek.class);
//모든 DayOfWeek Enum의 값을 담고있는 Set을 반환
EnumSet enumSet2 = EnumSet.allOf(DayOfWeek.class);
정적 팩토리 메소드(static factory method)만으로 EnumSet의 구현 객체를 반환받을 수 있습니다. 왜 이렇게 만든 걸까요?
EnumSet 내부를 살펴보자
(아래 코드는 설명을 위해서 간소화한 코드입니다.)
public abstract class EnumSet { //EnumSet은 abstract하여 객체 생성이 불가능하다.
...
//noneOf 메소드에서 상황에 따라 다른 구현체 객체들을 만들어서 반환해주고 있다.
public static noneOf(...) {
if (enumElementSize <= 64)
return new RegularEnumSet<>(...);
else
return new JumboEnumSet<>(...);
}
}
기본적으로 EnumSet은 abstract 키워드가 사용되기 때문에 객체로써 생성 및 사용이 불가능합니다.
그리고 EnumSet의 구현 객체를 반환 받을 때 사용한 noneOf
메소드를 살펴보면 내부적으로 EnumSet을 상속받은 RegularEnumSet
과 JumboEnumSet
을 생성하고 반환해 주고 있습니다. (상속받은 두개의 클래스 역시 생성자가 public 하지 않아, 사용자가 임의로 생성하여 사용할 수 없는 구조 입니다.)
왜 이렇게 만들었을까?
1. 사용자 편의성 - (사용자는 어떤 구현 객체가 적합한지 몰라도 상관없다)
RegularEnumSet
은 원소의 갯수가 적을 때 적합하고, JumboEnumSet
은 원소의 갯수가 많을때 적합하지만, 이는 EnumSet의 구현체들을 모두 알고 있는 사용자가 아니라면 난해한 선택지가 될 수도 있습니다. 하지만 EnumSet을 가장 잘 알고 있는 EnumSet 개발자가 적절한 구현 객체를 반환해준다면 EnumSet을 사용하는 입장에서는 어떤 구현체가 적합한지 고려하지 않아도 됩니다.
2. 사용자 편의성2 - (사용자는 빈번하게 발생되는 EnumSet초기화 과정을 간단히 진행할 수 있다.)
EnumSet이 다루는 Enum의 모든 원소들을 Set에 담는 행위는 빈번하게 수행될 것으로 예상되는 일입니다. 이러한 경우를 대비하여서 EnumSet의 allOf
라는 메소드를 사용하면 모든 Enum 원소가 담겨있는 EnumSet을 쉽게 반환받고 사용 할 수 있습니다.
3. EnumSet의 확장성과 유지보수의 이점
EnumSet을 유지보수하는 과정에서 RegularEnumSet
과 JumboEnumSet
이외에 다른 경우를 대비하는 구현 클래스가 추가 된다고 하여도 내부에 감추어져 있기 때문에, EnumSet을 사용하던 기존의 코드에는 전혀 영향이 없습니다. 심지어 RegularEnumSet
이 삭제된다 하더라도 사용자에게 영향이 없습니다. 이는 EnumSet의 확장성의 큰 이점으로 작용할 수 있습니다.
참고자료
- https://javarevisited.blogspot.com/2014/03/how-to-use-enumset-in-java-with-example.html
- 이펙티브 자바 - 조슈아 블로크 저
'Java' 카테고리의 다른 글
IntelliJ로 JUnit4 테스트 JUnit5로 변환하기 (2) | 2020.07.01 |
---|---|
String은 항상 StringBuilder로 변환될까? (4) | 2020.04.01 |
Set은 왜 get() 메소드가 없을까? (0) | 2019.07.09 |
EnumMap(EnumSet) 쓰면 좋을까? (vs HashMap) (2) | 2019.06.06 |
내부(inner) class와 내부(inner) static class 차이 (7) | 2019.06.02 |