[0829] 자바 스트림
#스트림
- 배열 및 컬렉션의 저장 요소를 하나씩 참조하여 람다식으로 처리할 수 있게 해주는 반복자.
- 선언형 프로그래밍(Declarative Programming)과 명령형 프로그래밍(Imperative Programming)
▪ 선언형 프로그래밍이란 코드에서 '무엇'에 집중하는 코드 작성 방법론을 말한다.
▪ 명령형 프로그래밍이란 코드에서 '어떻게'에 집중하는 코드 작성 방법론을 말한다.
▪ 선언형 프로그래밍은 내부의 동작 원리를 모르더라도 코드의 역할을 직관적으로 볼 수 있다.
- 스트림을 통해 선언형 프로그래밍이 가능하다.
// 명령형 프로그래밍
public class ImperativeProgramming {
public static void main(String[] args){
// List에 있는 숫자 중에서 5보다 큰 홀수의 합계 구하기
List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);
int sum = 0;
for(int number : numbers){
if(number > 5 && (number % 2 == 1)){
sum += number;
}
}
System.out.println("명령형 프로그래밍을 사용한 합계 : " + sum);
}
}
// 선언형 프로그래밍
public class DeclarativePrograming {
public static void main(String[] args){
// List에 있는 숫자들 중에서 5보다 큰 홀수의 합계 구하기
List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);
int sum =
numbers.stream()
.filter(number -> number > 5 && (number % 2 == 1))
.mapToInt(number -> number)
.sum();
System.out.println("선언형 프로그래밍을 사용한 합계 : " + sum);
}
}
▪ 각 메서드에서 람다식으로 데이터를 처리할 방법을 규정할 수 있음.
- 스트림을 통해 데이터 소스의 유형에 상관없이 같은 방식으로 데이터를 가공/처리 할 수 있다.
import java.util.*;
public class StreamExample {
public static void main(String[] args) {
// ArrayList 타입
List<String> animalList = enw ArrayList>?();
animalList.add("호랑이");
animalList.add("판다");
animalList.add("토끼");
// 배열 타입
String[] animalArray = {"호랑이", "판다", "토끼"};
// 스트림 생성
Stream<String> ListStream = animalList.stream();
Stream<String> ArrayStream = Arrays.stream(animalArray);
// 출력
ListStream.forEach(System.out::print);
ArrayStream.forEach(System.out::print);
}
}
//출력값
호랑이 판다 토끼 호랑이 판다 토끼
#스트림의 특징
(1) 스트림 처리 과정은 생성, 중간 연산, 최종 연상 총 세 단계(파이프라인)로 구성될 수 있다.
(2) 스트림은 원본 데이터 소스를 변경하지 않는다. (읽기만 함)
(3) 스트림은 일회용이다.
(4) 스트림은 내부 반복자이다.
-파이프라인
▪ 스트림의 생성, 중간 연산, 최종 연산 순으로 이어지는 단계를 지칭.
▪ 3단계가 모두 있는 구성을 완전체 파이프라인이라고 한다.
▪ 제공된 데이터 소스를 일원화 하여 스트림으로 작업한다.
▪ 중간 연산을 생략 가능.
▪ 최종 연산은 스트림의 요소를 소모하며 연산을 수행하기 때문에 단 한번의 연산만 가능.
- 내부 반복자
▪ 외부 반복자와 비교됨. (외부 반복자: for문, Iterator를 사용하는 while문)
▪ 외부 반복자는 데이터의 처리가 컬렉션 외부에서, 내부 반복자는 데이터의 처리가 컬렉션의 내부에서 일어난다.