비슷한 듯 안 비슷한 두 친구...
Steam API 란?
컬렉션, 배열 등의 저장 요소를 하나씩 참조하며 함수형 인터페이스를 적용하여 반복적으로 처리할 수 있도록 해주는 기능입니다.
컬렉션이란?
자바의 컬렉션은 데이터를 저장하고 관리하는 클래스의 집합을 의미합니다.
- List : 순서가 있는 데이터의 집합을 다루며 데이터의 중복을 허용합니다.
- Set : 순서를 유지하지 않는 데이터의 집합을 다루며, 중복을 허용하지 않습니다.
- Map : (Key, Value)의 쌍으로 이루어진 데이터의 집합입니다. Key는 중복을 허용하지 않습니다.
- Queue : 데이터가 입력된 순서대로 접근이 가능하며, 주로 데이터의 순서를 관리할 때 사용합니다.
람다식이란?
(int a, int b) -> a + b
// (파라미터) -> 표현
람다식은 함수형 프로그래밍을 지원하기 위한 도구입니다.
메서드를 간단하게 표현하고 코드의 가독성을 높이는 데 사용됩니다.
Stream API의 특징
1. 원본 데이터를 변경하지 않고 새로운 데이터를 생성합니다.
Stream API는 원본 데이터를 조회 한 뒤, stream을 통해 별도의 데이터를 생성합니다.
2. 재사용이 불가능 하며, 한번 사용되면 소비됩니다.
Stream을 재사용하면 IllegalStateException이 발생합니다.
3. Stream 생성 -> 중간 연산 -> 최종 연산을 통해 데이터가 생성됩니다.
stream() -> map, filter, reduce -> sum, count, collect... etc
위의 단계를 거쳐 결과 값을 얻습니다.
코드 예시
public int getFoodCountByCategory(String category) {
return foods.stream()
.filter(food -> food.getMenuCategory().equals(category))
.mapToInt(Food::getFoodCount)
.sum();
}
Category 별로 음식의 개수를 계산하는 메서드입니다.
새로운 stream을 생성한 뒤, 중간연산인 filter에서 food의 카테고리를 비교한 뒤, mapToInt를 통해 getFoodCount 메서드를 실행시킵니다. 그 후, 최종연산인 sum을 통해 계산을 하고 int 자료형으로 결과 값이 반환됩니다.
*StreamAPI의 다양한 기능들은 다른 글을 통해 자세히 설명해 드리겠습니다.
내부 반복자
내부 반복자가 뭐야? 안에서 반복한다는 뜻인가?
내부 반복자란 반복을 애플리케이션 라이브러리가 제어하고 개발자는 요소의 처리 방법만을 제공하는 방식입니다.
Stream API를 보면 filter, map 등 연산자를 통해서 개발자가 처리 방법만 제공해 줄 뿐이지 언제까지 반복하라는 말은 없습니다.
Iterator란?
Iterator란 자바의 컬렉션에 저장되어 있는 요소들을 순회하는 인터페이스이다.
컬렉션은 Stream API에 있는 설명을 보시면 됩니다. ☺️
Iterator의 특징
1. 정말 간단합니다.
Iterator은 Stream API에 비해 정말 간단합니다. (함수가 3개뿐입니다...!!!)
2. 데이터를 변경하지 않고 순회하는 역할만 합니다.
새로운 데이터를 생성하는 Stream에 비해 Iterator은 순회하는 역할만 합니다.
3. 재사용이 불가능합니다.
Iterator은 순회를 하기 때문에 한번 사용을 하면 모든 데이터를 전부 조회한 것입니다.
*반복문을 통해 전부 조회를 한 경우
그러므로 더 이상 요소가 없는 상태에서 조회를 또 하려고 하면 NoSuchElementException에러가 발생합니다.
코드 예시
public int getFoodCountByCategory(String category) {
int sum = 0;
Iterator<Food> iterator = foods.iterator();
while (iterator.hasNext()) { // 다음 요소가 있으면 return True
Food food = iterator.next();
if (food.getMenuCategory().equals(category)) {
sum += food.getFoodCount();
}
}
return sum;
}
stream API에 있는 코드 예시와 똑같은 코드를 Iterator로 구현해보았습니다.
이때 Iterator을 사용하는 부분은 다음 요소가 있는지 검사하는 hasNext 메서드와 다음 메서드로 넘겨주는 next 메서드뿐입니다. 단순 순회가 아닌 데이터 생성은 stream API가 훨씬 효율적이고 가독성이 높은 것 같습니다.
외부 반복자
이미 눈치를 채셨을 수도 있지만 Iterator은 Stream API와 달리 프로그래머가 반복문 구현을 해야 합니다.
이 처럼 사용자가 직접 컬렉션의 요소를 가져오고, 반복을 제어하는 방식을 외부 반복자라고 합니다.
정리
Stream API, Iterator 모두 자바에서 데이터를 처리하는 데 사용되지만 사용 방식과 목적이 다릅니다.
주로 데이터를 새로 생성하고 가공하는 데는 Stream API가 유리하며, 데이터를 순회하는 것에는 Iterator가 유리합니다. 또한 Stream API는 내부 반복자이기 때문에 사용자가 처리 방식만 제공하면 되지만 Iterator은 외부 반복자로써 사용자가 직접 반복을 구현하고 처리 방식을 결정해야 합니다.