반응형
자바8 이상 문법인 Stream을 알아보자
📌 서론
이번 포스트에서는 간단한 예제를 통해 stream을 이해해보는것이 목표다.
1. Stream 예제: 특정 문자열을 찾고 대문자로 변환
문자열의 List에서 특정 문자열을 찾고 그 문자열을 대문자로 변환하는 작업
- Stream을 사용하지 않고 for문을 사용한 코드
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ListExample {
public static void main(String[] args) {
// List를 생성한다.
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
// 결과를 저장할 새 List 생성
List<String> result = new ArrayList<>();
// List를 순회하며 "apple"을 찾고 대문자로 변환
for (String fruit : list) {
if (fruit.equals("apple")) {
result.add(fruit.toUpperCase());
}
}
// 결과 출력
System.out.println(result);
}
}
위의 코드를 for문을 제거하고 Stream으로 변환해보자
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class StreamExample {
public static void main(String[] args) {
// List 생성
List<String> list = Arrays.asList("apple", "banana", "cherry", "date", "elderberry");
// List를 Stream으로 변환하고 "apple"을 찾아 대문자로 변환
List<String> result = list.stream()
.filter(fruit -> fruit.equals("apple"))
.map(String::toUpperCase)
.collect(Collectors.toList());
// 결과 출력
System.out.println(result);
}
}
list.stream()
- list를 .stream() 메서드를 통해 Stream으로 변환시킨다.
.filter(fruit -> fruit.equals("apple"))
- filter는 말그대로 필터링을 하는 작업이다. stream으로 반복되는 list의 인자를 여기서는 fruit에 넣어서 이 fruit이라는 이름으로 내부의 필터링 로직에서 사용한다. 이제 list에서 넘어온 인자(fruit)이 "apple"인지 확인해서 맞다면 true를 반환하고 다음 단계에 데이터를 넘긴다.
.map(String::toUpperCase)
- filter를 통과해서 넘어온 값을 map 함수를 통해서 변환시킨다. String에서 toUpperCase메소드를 메소드 참조를 통해 사용한다. 그렇다면 "apple"을 "APPLE" 로 대문자로 변환시키게 된다.
.collect(Collectors.toList())
- filter()와 map()등의 중간연산이 모두 완료된 후에 collect메서드가 호출되어 결과를 최종적으로 리스트 형태로 모은다. (각 원소가 map을 마칠때마다 collect에 값을 넣지 않는다는 의미이다.)
1. 스트림의 중간 연산들은 레이지(lazy)하게 동작한다.
중간 연산이란?
- 위의 예시코드에서 .filter(), .map() 등이 중간 연산이다. 이런 연산들은 실제로는 데이터에 즉시 적용되지 않는다. 대신에 "이런 작업을 할 거야"라고만 표시한다.
최종 연산이란?
- .collect(), .forEach(), .sum() 등이 있다. 이 연산들이 호출되는 순간, 중간 연산에 적용될 모든 작업이 실제로 실행된다. 즉, .filter()나 .map() 같은 중간 연산을 정의해도, 실제로 그 연산이 실행되는 것은 최종 연산인 .collect()가 호출될 때라는 것이다.
List<String> result = list.stream()
.filter(fruit -> fruit.equals("apple"))
.map(String::toUpperCase)
.collect(Collectors.toList());
잠깐 흐름을 따라가 보자 (위에서 생성한 stream코드를 예시로 한다.)
- list.stream()을 사용해서 스트림을 생성한다.
- .filter(fruit -> fruit.equals("apple"))에서는 "나중에 apple만 골라내자"라고 표시만 해두게 된다.(중간 연산)
- .map(String::toUpperCase)에서는 "나중에 문자열을 대문자로 바꾸자"라고 표시만 해둔다.(중간 연산)
- .collect(Collectors.toList())가 호출되는 순간, 이전에 표시해 둔 모든 작업(filter와 map)을 실제로 수행하고, 그 결과를 리스트로 만든다.(최종 연산)
반응형
'JAVA' 카테고리의 다른 글
[Java] 동시성과 병렬 처리 part2: 함정, 고급 패턴, 성능 최적화 (1) | 2023.11.01 |
---|---|
[Java] 동시성과 병렬 처리 part1 (1) | 2023.10.31 |
[Java] Stream: mapToInt 함수로 점수 합산하기 (0) | 2023.09.27 |
[Java] ObjectMapper란 무엇인가? (0) | 2023.08.16 |
[Java] 익명 클래스 (Anonymous Class)란? (0) | 2023.08.09 |