JDK 8에 추가된 API로 함수형 인터페이스인 람다(lambda)를 활용할 수 있는 기술. 데이터를 추상화하고, 데이터를 다루는데 자주 사용되는 메서드를 정의한 API이다.
배열이나 컬렉션을 출력할 때, 코드를 간결하고 가독성있게 표현할 수 있는 API로 길게 늘어진 for문을 체이닝과 람다를 이용하여 보기 쉽게 정리할 수 있다.
이렇게 적어서는 잘 이해가 되지 않으므로 예제를 가지고 이해해보기로 했다!
2021.11.26 - [개발자가 될 때까지/JAVA] - [Java] 람다식 (Lambda Expression)
Stream API의 특징
- Stream API는 원본의 데이터를 조회하여 별도의 요소들로 Stream을 생성한다. 다시말해, 기존의 배열이나 컬렉션을 바꾸는게 아니라 기존의 것을 가공해서 탄생한 것들을 새롭게 저장한다.
그렇기 때문에 정렬이나 필터링 등의 작업은 별도의 Stream 요소들에서 처리가 된다. - Stream API는 일회용이기 때문에 Stream이 또 필요한 경우에는 Stream을 다시 생성해주어야한다.
- 내부 반복으로 작업을 처리한다.
Stream은 메소드 내부에 for문이나 while문 같은 반복문을 숨기고 있기 때문에, 보다 간결한 코드의 작성이 가능하다. - 병렬 처리를 지원한다parallelStream() 사용
Stream API를 이용하면 멀티 스레드 환경에 필요한 코드를 작성하지 않고도 데이터를 병렬로 처리할 수 있다.
Stream API의 연산구조
Stream API를 사용하기 위해서는 3가지 단계를 거친다.
생성 > 가공 연산 > 결과 연산
1. Stream 생성
Steram 객체를 생성하는 단계이다.
List<String> fruits = new ArrayList<>();
fruits.add("apple");
fruits.add("banana");
fruits.add("watermelon");
fruits.add("strawberry");
fruits.add("grape");
// Stream 생성
Stream<String> fruitsStream = fruits.stream();
가장 기본이 되는 stream()
을 사용하는 방식 외에도 다양한 방식의 스트림 생성 방식이 존재한다.
parallelStream()
를 이용하여 병렬처리를 할 수도 있고, bulider()
로 빌더 패턴을 사용할 수도 있다.
builder()는 체이닝의 마지막에 .build()
를 호출하면 빌더 스트림을 생성할 수 있다.
병렬처리?
한가지 작업을 서브 작업으로 나누고, 서브 작업들을 분리된 스레드에서 병렬적으로 처리한 후, 서브 작업들의 결과들을 최종 결합하는 방법
📌 더 많은 종류의 스트림 생성 방식 참조
https://madplay.github.io/post/introduction-to-java-streams
2. 중간 연산
생성된 Stream을 필터링하거나 가공하는 단계
retrun type이 Stream이기 때문에 연속해서 중간연산을 이어나가는 체이닝이 가능하다.
지원 메서드
메서드명 | 설명 |
filter() | 스트림 요소마다 조건문을 만족하는 요소로 구성된 스트림을 반환 |
map() | 스트림의 각 요소들을 특정 형태로 변환 |
distinct() | 스트림 요소들의 중복을 제거한 스트림을 반환 |
flatMap() | 중첩된 스트림 요소를 단일 원소 스트림으로 반환 |
limit() | 지정한 인덱스만큼 스트림 내의 요소 개수를 제한하여 새로운 스트림을 생성 |
skip() | 지정한 인덱스 만큼의 요소를 제외한 나머지 요소로 구성된 새로운 스트림을 생성 |
sorted() | 스트림 요소를 정렬하는 method로 기본적으로 오름차순으로 정렬 |
peek() | 스트림에 영향을 주지않고 스트림 요소에 특정 연산을 수행 |
filter
스트림 요소마다 조건문을 만족하는 요소로 구성된 스트림을 반환
if문과 같은 역할을 하는 메서드이다.
3. 결과 만들기
가공된 데이터로부터 원하는 결과를 만들기 위한 최종연산
return type이 Stream이 아니므로 더이상 체이닝 할 수 없다.
지원 메서드
메서드명 | 설명 |
collect() | 스트림의 결과를 모으기 위한 메서드로 스트림의 요소들을 List나 Set, Map등 다른 종류로 반환할 때 사용 |
forEach() | 스트림의 요소들을 순회(iterate)하면서 반복해서 처리해야 하는 경우 사용 |
reduce() | 스트림의 요소들을 더 작은 컬렉션이나 단일 값으로 만듦 map과 비슷하게 동작하지만 개별연산이 아니라 누적연산이 이루어진다는 차이 존재 |
findFirst() | 스트림에서 지정한 첫번째 요소를 찾는 메서드 |
findAny() | 스트림에서 지정한 첫번째 요소를 찾는 메서드 parallelStream()와 함께 사용 |
anyMatch() | 스트림의 요소중 특정 조건을 만족하는 요소가 하나라도 있는지 검사 |
allMatch() | 스트림의 요소중 특정 조건을 모두 만족하는지 검사 |
noneMatch() | 스트림의 요소중 특정 조건을 만족하는 요소가 하나도 없는지 검사 |
count() | 스트림의 원소들로 부터 전체 개수 구하기 위한 메서드 |
min() | 스트림의 원소들로 부터 최소값 구하기 위한 메서드 |
max() | 스트림의 원소들로 부터 최대값을 구하기 위한 메서드 |
sum() | 스트림 원소들의 합계를 구하는 메서드 |
average() | 스트림 원소들의 평균을 구하는 메서드 |
++ 추가 중입니다.
참고
https://mangkyu.tistory.com/112
'Study > JAVA' 카테고리의 다른 글
[JAVA] String, StringBuffer, StringBuilder 차이 및 장단점 (0) | 2021.11.27 |
---|---|
[Java] 람다식 (Lambda Expression) (0) | 2021.11.26 |
[Java] 컬렉션 (Collection) - Map (0) | 2021.11.23 |
[JAVA] 컬렉션(Collection) - Set (0) | 2021.11.23 |
[Java] 컬렉션(Collection) - 리스트(List): ArrayList, LinkedList, Vector (0) | 2021.11.16 |