public enum LottoRank {
FIFTH(3, 5000),
FOURTH(4, 50000),
THIRD(5, 1500000),
SECOND(5, 30000000),
FIRST(6, 2000000000);
private final int correctNumber;
private final int prizeAmount;
LottoRank(final int correctNumber, final int prizeAmount) {
this.correctNumber = correctNumber;
this.prizeAmount = prizeAmount;
}
public static LottoRank valueOf(int sameCount, boolean bonus) {
if (sameCount == 5) {
return checkSecondOrThird(bonus);
}
return Arrays.stream(LottoRank.values())
.filter(lottoRank -> lottoRank.getCorrectNumber() == sameCount)
.findFirst()
.orElse(null);
}
로또에 당첨된 사람들을 enum 값으로 표현했는데 당첨되지 않은 사람들은 따로 만들지 않았었다. 그래서 당첨되지 않은 사람들은 null
을 반환해서 해결했었다. 하지만 null
을 반환하면서 찜찜한 기분이 있었는데 마침 이펙티브 자바에 해당 내용이 있길래 읽으며 정리해봤다.
public class CandyStore {
private final List<Candy> candiesInStock;
public List<Candy> getCandiesInStock() {
return candiesInStock.isEmpty() ? null : new ArrayList<>(candiesInStock);
}
}
만약 사탕가게의 재고를 파악하는 프로그램에서 재고가 없을 경우 null
을 반환한다고 하면, 해당 메서드를 이용할 때 null
상황을 처리하는 코드를 추가로 작성해야한다.
List<Candy> candies = candyStore.getCandiesInStock();
if (candies != null && candies.contains(Candy.RED)) {
System.out.println("빨간 사탕이 있지");
}
만약 null
에 대해 처리를 안해준다면 NullPointerException
이 발생할 것이다. 그래서 저자는 빈 컬렉션이나 배열을 반환하라고 한다.
혹자는 빈 컨테이너를 할당하는 데도 비용이 드니 null을 반환하는 쪽이 낫다고 할 수 있다.하지만 이는 두가지 면에서 틀린 주장이다.
빈 컨테이너를 할당하는 것이 성능 저하의 주범이라고 확인되지 않는 한 효율적인 프로그램보다는 유지보수에 적합한 설계를 가져가는 것이 좋다.
아이템 67 최적화는 신중히 하라 - 빠른 프로그램보다는 좋은 프로그램을 작성하라
public List<Candy> getCandiesInStock() {
return new ArrayList<>(candiesInStock);
}
혹여나 이 코드가 성능에 저하를 불러일으킨다 하더라도 아래 코드처럼 작성한다면 해결될 것이다. 그리고 꼭 개선 결과를 확인하자.
public List<Candy> getCandiesInStock() {
return candiesInStock.isEmpty() ? Collections.emptyList()
: new ArrayList<>(candiesInStock);
}
public enum LottoRank {
NOTHING(0, 0),
FIFTH(3, 5000),
FOURTH(4, 50000),
THIRD(5, 1500000),
SECOND(5, 30000000),
FIRST(6, 2000000000);
private final int correctNumber;
private final int prizeAmount;
LottoRank(final int correctNumber, final int prizeAmount) {
this.correctNumber = correctNumber;
this.prizeAmount = prizeAmount;
}
public static LottoRank valueOf(int sameCount, boolean bonus) {
if (sameCount == 5) {
return checkSecondOrThird(bonus);
}
return Arrays.stream(LottoRank.values())
.filter(lottoRank -> lottoRank.getCorrectNumber() == sameCount)
.findFirst()
.orElse(NOTHING);
}
null
로 반환하지 않고 NOTHING
을 반환해서 해결했다. 추가로 이번 미션 리뷰어인 던은 아래처럼 생각한다고 공유받았다.
이펙티브 자바 p.323 "nulll이 아닌, 빈 컬렉션이나 배열을 반환하라"