Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java에서 Iterator와 Spliterator의 차이점 완벽 정리

Java에서 IteratorSpliterator는 모두 컬렉션(Collection)의 요소를 순회하기 위해 사용되는 인터페이스입니다. 하지만 두 인터페이스는 도입 배경과 동작 방식에서 중요한 차이를 보이며, 특히 멀티코어 환경에서의 성능 최적화 측면에서 그 차이가 두드러집니다.

Spliterator란 무엇인가?

Spliterator(Split + Iterator)는 Java 8에서 병렬 처리(Parallelism)를 지원하기 위해 새롭게 도입된 인터페이스입니다. 주어진 데이터 집합을 여러 조각으로 분할(split)한 뒤, 서로 독립적인 스레드에서 각 조각을 동시에 처리할 수 있도록 설계되었습니다.

Spliterator는 요소를 병렬 방식뿐만 아니라 순차적(Sequential) 방식으로도 순회할 수 있으며, Stream API와 함께 사용될 때 특히 강력한 성능을 발휘합니다.

Spliterator의 주요 메서드

  • trySplit() – 데이터 집합을 여러 조각으로 분할하고, 분할된 부분을 담당하는 새로운 Spliterator를 반환합니다.
  • tryAdvance() – Iterator의 hasNext()/next() 메서드에 해당하며, 다음 요소가 존재하면 해당 요소에 지정된 작업을 수행합니다.
  • getExactSizeIfKnown() – 크기를 미리 알 수 있는 경우 데이터 집합의 정확한 크기를 반환합니다.
  • forEachRemaining() – 남은 모든 요소에 대해 지정된 작업을 한 번에 수행합니다.

Iterator vs Spliterator 핵심 차이점

번호구분 기준IteratorSpliterator
1 기본 용도 컬렉션의 요소를 순회하는 데 사용됩니다. 컬렉션뿐만 아니라 Stream에서도 사용할 수 있습니다.
2 대량 처리(Bulk Operation) 요소를 하나씩만 순회할 수 있습니다. 요소를 일괄(bulk) 단위로 순회할 수 있습니다.
3 순차 / 병렬 처리 순차적(Sequential) 방식으로만 순회 가능합니다. 순차적 방식과 병렬(Parallel) 방식 모두 지원합니다.
4 외부 / 내부 반복자 외부 반복(External Iteration) 방식을 사용합니다. 개발자가 직접 순회를 제어합니다. 내부 반복(Internal Iteration) 방식을 사용합니다. 순회 제어를 프레임워크에 위임합니다.

Spliterator 예제 코드

다음은 trySplit()을 사용해 리스트를 두 개의 조각으로 나눈 뒤, 각각 순회하는 예제입니다.

public class Main {
    public static void main(String args[]) {
        List<Integer> listOfInteger = new ArrayList<>();
        listOfInteger.add(78);
        listOfInteger.add(10);
        listOfInteger.add(20);
        listOfInteger.add(30);

        Spliterator<Integer> s = listOfInteger.spliterator();
        Spliterator<Integer> s1 = s.trySplit();

        System.out.println("Traverse First Half");
        s.forEachRemaining(System.out::println);
        System.out.println("Traverse Second Half");
        s1.forEachRemaining(System.out::println);
    }
}

마무리 정리

단순히 컬렉션을 순서대로 하나씩 읽는 것이 목적이라면 기존의 Iterator로 충분합니다. 하지만 대용량 데이터를 여러 스레드로 나누어 병렬로 처리해야 하는 상황이라면 Spliterator가 훨씬 적합한 선택입니다. Java 8 이상의 환경에서 Stream API의 parallelStream()을 활용한다면, 내부적으로 Spliterator가 자동으로 데이터를 분할하여 병렬 처리를 수행해 줍니다.