본문 바로가기

우아한테크코스

[2주차] 정적 팩토리 메서드로 만든 컬렉션은 Immutable하다

2주차 미션인 숫자야구를 진행하던 도중, 1주차 피드백 중 배열 대신 컬렉션을 사용하라 라는 문구가 생각났다.

 

그래서 배열로 구현했던 computerNumbers를 List로 바꿔보기로 했다.

 

 

배열로 구현한 코드

 

이 때 computerNumbers 는 중복되면 안되는 규칙이 있었는데

int[] computerNumbers = new int[3];

로 할당한 computerNumbers 배열은 0으로 자동 초기화가 되기 때문에 0으로 비교하여 숫자가 할당 되었는지 판단 할 수 있었습니다. 하지만 List는 0으로 초기화 되지 않기 때문에 이런 비교가 불가능했습니다.

 

 

 

List로 구현한 코드


 

List<Integer> computerNumbers = new ArrayList<>();

이런 비교가 불가했다. 아직 숫자를 삽입하기 전인 computerNumbers의 i 번째 인수에 접근하자 당연하게도 IndexOutOfBoundsException 가 발생했습니다.

 

 

 

 

 

 

 

첫 번째 시도

 

List<Integer> computerNumbers = List.of(0,0,0);

첫 번째 시도는 Java 9 에서 추가된 List 의 정적 팩토리 메서드인 of 를 사용하여 0으로 초기화 하는 것이었습니다. 하지만 이번엔 UnsupportedOperationException 가 발생하였습니다. 왜 그럴까?

 

 

실제 List의 of 메서드 입니다.

static <E> List<E> of(E e1, E e2, E e3) {
    return new ImmutableCollections.ListN<>(e1, e2, e3);
}

ImmutableCollections 의 List를 반환하는 모습입니다. 이 때 ImmutableCollection은 아이템 추가, 수정, 제거가 불가능한 컬렉션입니다. 

 

 

 

for (int i = 0; i < 3; i++) {
    int newNumber = assignNumber(computerNumbers);
    computerNumbers.add(i, newNumber);
}

그렇기 때문에 computerNumbers 에 add 하려는 순간 UnsupportedOperationException가 발생한 것이었습니다.

 

 

 

 

 

 

 

두 번째 시도

 

 

List<Integer> computerNumbers = new ArrayList<>(List.of(0, 0, 0));

 

이렇게 List.of(0,0,0) 을 ArrayList로 감싸 반환하는 방법입니다. 이렇게 하자 정상적으로 작동하는 것을 확인 할 수 있었습니다. 당연하게도 new로 할당한 ArrayList는 ImmutableCollection 이 아니라 아이템 추가, 수정, 제거가 가능합니다.

 

 

 

List<Integer> computerNumbers = new ArrayList<>();
computerNumbers.addAll(List.of(0, 0, 0));

이렇게 addAll 메서드로 추가해 주어도 정상적으로 작동하는 것을 확인 할 수 있었습니다.

 

 

 

 

 

 

후기

 

배열을 컬렉션으로 바꾸고 보니 컬렉션의 다양한 API를 사용할 수 있어서 훨씬 관리가 용이해졌습니다. 하지만 Set 을 이용해 중복을 제거하면 훨씬 간결한 코드가 될 것 같습니다. 추후 Set으로 ComputerNumbers의 중복을 제거하는 코드로 리팩토링 하려합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Recent Posts
Popular Posts
Recent Comments