<aside> 📌 filter()함수는 어떻게 동작할까?
</aside>
filter()
메서드는 주어진 조건에 맞는 요소들만을 선택하여 새로운 스트림을 생성한다.filter().map()
**과 같이 메서드를 연결하는 것을 메서드 체이닝이라고 하는데 이 경우, filter()
메서드가 먼저 호출되어 조건에 맞는 요소가 선택된 후, 그 결과 요소를 바로 map()
메서드로 전달한다. map()
메서드는 요소를 주어진 함수에 적용하여 그 결과로 새로운 스트림을 생성한다.
스트림의 처리방식 설명
중간 연산(intermediate operation)
**과 **최종 연산(terminal operation)
**이다.filter()
**와 **map()
**은 중간 연산에 해당하며, 이들은 스트림을 변환만 할 뿐 실제로는 어떤 연산도 수행하지 않는다. 실제 연산은 최종 연산이 호출될 때 이루어진다.'지연 연산'
또는 **'늦은 연산'
**이라고 부른다. 따라서 **filter()
**가 모든 요소를 '다 돌린다'는 표현보다는, 최종 연산이 호출될 때 필요한 요소만 선택하여 연산이 수행된다는 표현이 더 정확할 것이다.import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
// 1. 원본 리스트 생성
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 2. Stream 생성 및 filter, map 연산 수행
List<Integer> evenSquares = numbers.stream() // 스트림 생성
.filter(n -> n % 2 == 0) // 필터링: 짝수만 선택
.map(n -> n * n) // 매핑: 각 요소를 제곱
.collect(Collectors.toList()); // 최종 연산: 리스트로 변환
// 3. 결과 출력
System.out.println(evenSquares); // [4, 16, 36, 64, 100]
}
}
stream()
, filter()
, **map()
**은 모두 중간 연산이다. 이들은 실제로는 어떤 연산도 수행하지 않고, 대신 연산을 나타내는 새로운 스트림을 반환한다. 이렇게 반환된 스트림은 다음 연산을 위한 '레시피'와 같다.collect()
**와 같은 최종 연산이 호출될 때 이루어진다. 이 때, 중간 연산들이 지정한 순서대로 각 요소에 적용된다. 이를 '지연 연산' 또는 '늦은 연산'이라고 부른다.filter()
**와 map()
연산은 **collect()
**가 호출될 때까지 실제로 수행되지 않는다. **collect()
**가 호출되면, **filter()
**와 map()
연산이 지정한 순서대로 각 요소에 적용되며, 이 결과로 생성된 새로운 리스트가 반환된다.filter()
**가 모든 요소를 '다 돌린다'는 표현보다는, 최종 연산이 호출될 때 필요한 요소만 선택하여 연산이 수행된다는 표현이 더 정확하다. 이는 필요 이상의 연산을 방지하여 성능을 향상시키는 데 도움이 된다.List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
List<Integer> squaresOfOdds = numbers.stream()
.filter(n -> {
System.out.println("Filtering " + n);
return n % 2 != 0;
})
.map(n -> {
System.out.println("Mapping " + n);
return n * n;
})
.collect(Collectors.toList());
Filtering 1
Mapping 1
Filtering 2
Filtering 3
Mapping 3
Filtering 4
Filtering 5
Mapping 5
Filtering 6
Filtering 7
Mapping 7
Filtering 8
Filtering 9
Mapping 9
Filtering 10
<aside> 📌 결국 filter에서는 다 연산하는게 아닌가? 그럼 filter()메서드가 걸러내는작업은 뭘까?
</aside>
filter()
메서드는 스트림의 모든 요소에 대해 호출되며, 주어진 조건에 따라 일부 요소를 걸러낸다. 이는 연산이라고 볼 수 있다. 그러나 이 연산은 필요한 요소만 선택하는 역할을 하며, 이후의 연산들은 필터링을 통과한 요소에 대해서만 수행된다.filter()
메서드는 모든 요소를 '다 돌린다'는 표현이 맞다. 그러나 이후의 연산들은 필터링을 통과한 요소에 대해서만 수행되므로, 불필요한 연산을 방지하고 성능을 향상시킬 수 있다.'단계별 처리'
**라는 특성 때문이다. 스트림은 각 요소를 독립적으로 처리하므로, 한 요소에 대한 모든 연산을 완료한 후 다음 요소로 넘어간다. 따라서 filter()
연산이 통과되지 않은 요소는 map()
연산 등에 전달되지 않아, 불필요한 연산을 방지하고 성능을 향상시킬 수 있다.