JDK21에서 Sequenced Collections이 후보에서 제안 상태로 승격되었다. 이는 해당 기능이 릴리즈될 가능성이 높아졌다는 것을 의미한다.

Sequenced Collections이 왜 등장하게 되었는지, 무엇인지 알아보자.

등장 배경

JCF는 요소의 저장 순서의 유무를 나타내는 컬렉션 유형이 없으며, 이러한 컬렉션에 적용되는 균일한 작업 집합이 없다.

이러한 이유로 불만이 발생했다.

예를 들어, ListDeque저장 순서를 유지하지만, supertype인 Collection그렇지 않다.

비슷하게, Set저장 순서를 유지하지 않지만 subType인 SortedSetLinkedHashSet저장 순서를 유지한다.

저장 순서를 지원하는 것은 타입 계층에 분산되어 있어서 API의 유용한 특정 개념을 표현하기 어렵게 만든다.

관련된 문제는 뷰 컬렉션이 종종 더 약한 의미로 downgrade 되도록 강요된다는 것이다.

LinkedHashSetCollections::unmodifiableSet으로 래핑 하면 순서가 사라진 Set이 된다.

이렇게 순서와 관련된 작업을 정의하는 인터페이스가 없으면, 연산은 일관성이 없거나 누락될 수 있다.

각 collection의 첫 번째 요소와 마지막 요소를 꺼내는 방법은 다음과 같다.

  First element Last element
List list.get(0) list.get(list.size() - 1)
Deque deque.getFirst() deque.getLast()
LinkedHashSet linkedHashSet.iterator().next() // missing

LinkedHashSetCollections.reverse()와 같은 역방향 반복을 지원하지 않기 때문에 모든 요소를 순회하는 방법밖에 없다.

따라서, 저장 순서를 유지하는지에 대한 인터페이스를 정의해 이들에게만 사용할 수 있는 연산들이 필요하다.

변경된 JCF 계층 구조

계층 구조가 다음과 같이 변경되며 어떤 Collection이 저장 순서를 유지하는지 명확하게 알 수 있다.

SequencedCollection은 다음과 같은 메서드를 지원하며, 각자 하위 인터페이스 별로 추가되는 메서드들이 따로 있다.

interface SequencedCollection<E> extends Collection<E> {
    // new method
    SequencedCollection<E> reversed();
    // methods promoted from Deque
    void addFirst(E);
    void addLast(E);
    E getFirst();
    E getLast();
    E removeFirst();
    E removeLast();
}

결론

순서를 유지하는 인터페이스를 도입하여 순서와 관련된 일관된 작업을 할 수 있도록 한다.

일관된 작업은 리스트의 요소를 첫 번째부터 접근하거나, 마지막부터 접근하거나, 역순으로 처리하는 등 통일된 API를 제공한다.


원문에 다음과 같은 문구가 있었다.

"Life can only be understood backwards; but it must be lived forwards." - Kierkegaard

인생에서 일어난 일을 당장 이해할 수 없지만 지나고 되돌아보면 그것을 이해할 수 있다는 것, 그러나 삶은 앞으로 살아가며 이해하고 경험해야 한다는 뜻이다.

컬렉션도 일단 작업을 진행하고 거꾸로 돌아보며 이해할 수 있다는 것일까.


참고 문서

+ Recent posts