JAVA 웹 개발 패키지 - 패스트캠퍼스/Chapter6
스트림(Stream) , reduce() 연산
giggs
2022. 1. 18. 11:22
스트림 이란?
- 자료의 대상과 관계없이 동일한 연산을 수행
- 배열, 컬렉션을 대상으로 연산을 수행함
- 일관성 있는 연산으로 자료의 처리를 쉽고 간단하게 함
- 자료 처리에 대한 추상화가 구현되었다고 함
- 한번 생성하고 사용한 스트림은 재사용할 수 없음
- 자료에 대한 스트림을 생성하여 연산을 수행하면 스트림은 소모됨(최종 연산이 이루어질 때 소모됨)
- 다른 연산을 수행하기 위해서는 스트림을 다시 생성해야 함
- 스트림 연산은 기존 자료를 변경하지 않음
- 자료에 대한 스트림을 생성하면 스트림이 사용하는 메모리 공간은 별도로 생성되므로 연산이 수행돼도 기존 자료에 대한 변경은 발생하지 않음
- 스트림 연산은 중간 연산과 최종 연산으로 구분됨
- 스트림에 대해 중간 연산은 여러 개의 연산이 적용될 수 있지만 최종 연산은 마지막에 한 번만 적용됨
- 최종 연산이 호출되어야 중간 연산에 대한 수행이 이루어지고 그 결과가 만들어짐
- 따라서 중간 연산에 대한 결과를 연산 중에 알 수 없음 이를 '지연 연산'이라 함
배열 스트림 생성 ( doble / int / long 등 )
다양한 stream 중 IntStream 메서드 확인 ( 나머지도 비슷비슷하다)
다른 연산을 수행하기 위해서는 스트림을 다시 생성해야 함
중간 연산과 최종 연산
- 중간 연산의 예 - filter(), map(), sorted() 등
- 조건에 맞는 요소를 추출(filter)하거나 요소를 변환함(map)
- 최종 연산이 호출될 때 중간 연산이 수행되고 결과가 생성됨
- 문자열 리스트에서 문자열의 길이가 5 이상인 요소만 출력하기
sList.stream().filter(s->s.length() >= 5).forEach(s->System.out.println(s));
filter()는 중간 연산이고, forEach()는 최종 연산임
- 고객 클래스 배열에서 고객 이름만 가져오기
customerList.stream().map(c->c.getName()).forEach(s->System.out.println(s));
map()은 중간 연산이고, forEach()는 최종 연산임
- 중간 연산과 최종 연산에 대한 구현은 람다식을 활용함
- 최종 연산의 예 - forEach(), count(), sum() 등
- 스트림이 관리하는 자료를 하나씩 소모해가며 연산이 수행됨
- 최종 연산 후에 스트림은 더 이상 다른 연산을 적용할 수 없음
- forEach() : 요소를 하나씩 꺼내 옴
- count() : 요소의 개수
- sum() : 요소들의 합
~~. ~~. ~~ 점으로 이어져서 가독성은 떨어지지만 if, for문을 써야 한다던지 여러 가지 조건들이 있는 경우에도
한 줄로 표현 가능한 장점이 있다.
컬렉션 스트림 생성
중간 연산자와 최종 연산자 사용
새로운 연산을 수행하기 위해서는 기존의 스트림은 재사용할 수 없고 stream() 메서드를 호출하여 스트림을 다시 생성해야 함
람다식 - 가상 클래스와 가상 객체 존재하는 것이다.
연산 수행에 대한 구현을 할 수 있는 reduce() 연산
reduce() 연산
- 정의된 연산이 아닌 프로그래머가 직접 구현한 연산을 적용
- 최종 연산으로 스트림의 요소를 소모하며 연산을 수행
- reduce() 메서드의 두 번째 요소로 전달되는 람다식에 따라 다양한 기능을 수행할 수 있음
- 람다식을 직접 구현하거나 람다식이 긴 경우 BinaryOperator를 구현한 클래스를 사용함
reduce() 연산자
stream의 정해져 있는 중간 / 최종 연산 메서드가 아닌
프로그래머가 reduce() 한 BinaryOperator로 연산 사용하겠다.
연산 직접 구현 -
- reduce() 메서드의 두 번째 요소로 전달되는 람다식에 따라 다양한 기능을 수행할 수 있음
- 람다식을 직접 구현하거나 람다식이 긴 경우 BinaryOperator를 구현한 클래스를 사용함
람다식을 이용해서 - 스트림에서 제공되는 중간 연산 최종 연산 외에 - 프로그래머가 직접 연산을 구현할 수 있다.
reduce() 메서드에 2번째 파라미터 부분으로!
람다식으로 구현 부분이 너무 길면 BinaryOperator를 구현하고 / 구현한 클래스로 인터페이스화 해주고 get
review
Stream
배열과 컬렉션을 대상으로 연산을 수행
중간 연산과 최종 연산이 있고, 최종 연산이 호출될 때 수행되고 결과가 생성된다.
최종 연산 후에 스트림은 소모되는 개념으로 다른 연산에 적용할 수 없음 - 다시 생성해서 사용해야 됨
중간 연산과 최종 연산에 대한 구현은 람다식을 활용한다.
프로그래머가 직접 연산을 구현하는 reduce() 연산도 가능하다.
배열과 컬렉션에 대한 스트림을 만들고 람다식을 활용해
Stream(). - 중간 연산과 최종 연산을 사용하는 방법
stream(). reduce() - 내가 직접 연산을 구현하여 사용하는 방법 - 실습하였다.
점점점(~.~.~.~)으로 이루어지는 코드가 한 번에 알아볼 수 있는 가독성은 떨어졌지만
복잡한 과정과 조건이 - 가상 내부 클래스 - 람다식 - 스트림의 개념으로 한 줄의 코드로 작성되었다.
Sream에 정해진 연산 외에도 여러 조건들을 내가 직접 구현해서 사용할 수 있었다.
이 부분은 큰 장점으로 앞으로 많이 사용될 거 같다.
Stream 은 메모리 공간을 별도로 생성해서 작업하고 소모되고 하는 것이라서
기존의 자료들에도 영향을 주지 않는 부분도 큰 장점인 것 같다.