[Java] 스트림(Stream)
2022. 2. 24. 03:47ㆍBack-end/Java
스트림(Stream)이란?
- 자료의 대상과 관계없이 동일한 연산을 수행한다
- 배열, 컬렉션을 대상으로 연산을 수행한다
- 일관성 있는 연산으로 자료 처리를 쉽고 간단하게 한다
- 자료 처리에 대한 추상화가 구현되어있다
- 한번 생성하고 사용한 스트림은 재사용할 수 없다
- 자료에 대한 스트림을 생성하여 연산을 수행하면 스트림은 소모된다
- 다른 연산을 수행하기 위해서는 스트림을 다시 생성해야 한다
만약 한번 사용한 스트림을 재사용하면
java.lang.IllegalStateException: stream has already been operated upon or closed
(스트림이 이미 작동되었거나 닫혔습니다)
이렇게 에러가 나는 것을 확인할 수 있다
int[] arr = {1,2,3};
int sum = Arrays.stream(arr).sum();
long count = Arrays.stream(arr).count();
System.out.println(sum);
System.out.println(count);
// Console
// 6
// 3
그래서 스트림은 사용할 때마다 생성해줘야 한다
- 스트림 연산은 기존 자료를 변경하지 않는다
- 자료에 대한 스트림을 생성하면 스트림이 사용하는 메모리 공간은 별도로 생성된다
- 연산이 수행돼도 기존 자료에 대한 변경은 발생하지 않는다
중간 연산과 최종 연산
- 스트림 연산은 중간 연산과 최종 연산으로 구분된다
- 스트림에 대해 중간 연산은 여러 개의 연산이 적용될 수 있지만 최종연 산은 마지막에 한 번만 적용된다
- 최종 연산이 호출되어야 중간 연산에 대한 수행이 이루어지고 결과가 만들어진다
- 중간 연산에 대한 결과는 연산 중에 알 수 없으며 이를 지연 연산이라고 한다
- 중간 연산의 예로는 filter(), map(), sorted() 등이 있다
- 조건에 맞는 요소를 추출(filter)하거나 변환(map)한다
- 최종 연산이 호출될 때 중간 연산이 수행되고 결과가 생성된다
- 최종 연산의 예로는 forEach(), count(), sum() 등이 있다
- 스트림이 관리하는 자료를 하나씩 소모해가며 연산이 수행된다
- 최종 연산 후에 스트림은 더 이상 다른 연산을 적용할 수 없다
람다식을 활용해서 중간 연산과 최종 연산에 대한 구현을 해보자
문자열 리스트에서 길이 조건으로 해당 요소만 출력하는 예제
stringList.stream().filter(s -> s.length() >= 5).forEach(s -> System.out.println(s));
여기서 filter()는 중간 연산이고 forEach()가 최종 연산이다
고객 클래스 배열에서 해당 고객 이름만 출력하는 예제
customerList.stream().map(c -> c.getName()).forEach(c -> System.out.println(c));
map()는 중간 연산이고 forEach()는 최종 연산이다
마지막으로 ArrayList에 스트림을 생성하고 사용해보자
public class ArrayListStreamTest {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("문자열 하나");
list.add("문자열 둘");
list.add("문자열 셋");
Stream<String> stream = list.stream(); // 자바 컬렉션은 스트림을 호출할 수 있다
stream.forEach(s -> System.out.println(s));
System.out.println();
list.stream().sorted().forEach(s -> System.out.println(s));
System.out.println();
list.stream().map(s -> s.length()).forEach(s -> System.out.println(s));
System.out.println();
list.stream().filter(s -> s.length() > 5).forEach(s -> System.out.println(s));
}
}
실행 시 출력 결과
문자열 하나
문자열 둘
문자열 셋
문자열 둘
문자열 셋
문자열 하나
6
5
5
문자열 하나
반응형
'Back-end > Java' 카테고리의 다른 글
[Java] 스트림(Stream) 활용 예제 (0) | 2022.02.26 |
---|---|
[Java] 스트림(Stream) - reduce() (0) | 2022.02.26 |
[Java] 객체 지향 프로그래밍 vs 람다식 (0) | 2022.02.23 |
[Java] 함수형 인터페이스로 람다식 구현 (0) | 2022.02.22 |
[Java] 함수형 프로그래밍 - 람다식(Lambda expression) (1) | 2022.02.22 |