Java 컬렉션 프레임워크는 데이터 그룹을 저장하고 조작하기 위해 사용됩니다. 컬렉션은 메모리 내(in-memory) 데이터 구조로, 모든 요소는 컬렉션에 추가되기 전에 반드시 계산(메모리에 적재)되어야 합니다.
반면 Stream API는 오직 데이터 그룹을 처리하는 용도로만 사용됩니다. 스트림은 원본 컬렉션을 수정하지 않으며, 파이프라인으로 연결된 연산에 따라 결과만 제공합니다.
컬렉션과 스트림의 주요 차이점
| 번호 | 구분 기준 | 컬렉션(Collections) | 스트림(Streams) |
|---|---|---|---|
| 1 | 기본 개념 | 데이터 그룹을 저장하고 조작하는 데 사용됩니다. | Stream API는 데이터 그룹을 처리하는 용도로만 사용됩니다. |
| 2 | 패키지 | 모든 클래스와 인터페이스는 java.util 패키지에 포함되어 있습니다. | 모든 클래스와 인터페이스는 java.util.stream 패키지에 포함되어 있습니다. |
| 3 | 즉시/지연 평가(Eager/Lazy) | 컬렉션의 모든 요소는 처음부터 즉시 계산됩니다. | 스트림에서는 중간 연산(intermediate operations)이 지연(lazy) 방식으로 처리됩니다. |
| 4 | 데이터 수정 | 컬렉션에서는 요소를 추가하거나 삭제할 수 있습니다. | 스트림은 수정할 수 없습니다. |
| 5 | 외부/내부 반복자 | 컬렉션은 외부 반복자를 통해 직접 순회(iteration)합니다. | 스트림은 내부적으로 반복을 수행합니다. |
컬렉션 사용 예제
public class CollectionsExample {
public static void main(String[] args) {
List<String> laptopList = new ArrayList<>();
laptopList.add("HCL");
laptopList.add("Apple");
laptopList.add("Dell");
Comparator<String> com = (String o1, String o2) -> o1.compareTo(o2);
Collections.sort(laptopList, com);
for (String name : laptopList) {
System.out.println(name);
}
}
}위 예제에서는 컬렉션에 요소를 저장한 뒤, Collections.sort()로 직접 정렬하고 for-each 문으로 외부 반복을 수행했습니다.
스트림 사용 예제
public class StreamsExample {
public static void main(String[] args) {
List<String> laptopList = new ArrayList<>();
laptopList.add("HCL");
laptopList.add("Apple");
laptopList.add("Dell");
laptopList.stream().sorted().forEach(System.out::println);
}
}반면 스트림 예제에서는 stream().sorted().forEach() 한 줄로 정렬과 출력이 동시에 처리됩니다. 반복 로직이 내부적으로 수행되므로 코드가 훨씬 간결해지고 가독성이 향상됩니다.
정리
컬렉션은 데이터를 저장·관리하는 자료구조이고, 스트림은 저장된 데이터를 효율적으로 처리하기 위한 파이프라인입니다. Java 8 이후에는 스트림의 지연 평가와 내부 반복 특성을 활용하면 선언형 코드 작성이 가능해져, 복잡한 데이터 처리 로직을 더욱 깔끔하게 구현할 수 있습니다.