Stream
- Collection 요소(List,Queue) 등의 데이터 흐름 처리하는데 사용 된다
- 일반적으로 stream - 가공 - 수집 단계를 거친다
스트림(Stream)은 자바 8부터 추가된 기능으로, 데이터의 흐름을 처리하는 데 사용되는 추상화된 기능입니다.
Collection 요소(List,Queue)를 람다식으로 처리하도록 지원하는 함수형 프로그래밍 기법이라고 볼 수 있습니다.
스트림을 사용하면 반복자를 사용하지 않고도 원하는 데이터를 필터링하고 맵핑하는 등의 복잡한 연산을 수행할 수 있습니다.
스트림은 원본 데이터를 변경하지 않고, 새로운 결과를 생성합니다.
또한, 스트림은 "지연 연산"을 합니다.
즉, 필요한 최종 결과를 만들기 위해 중간 연산을 실행하지 않고 최종 연산 시점에 한번에 처리합니다.
Java에서 말하는 스트림이란
- 데이터 처리를 위한 추상화: 스트림은 데이터 처리를 위한 추상화 계층을 구현합니다.
- 일회성 사용: 스트림을 생성하고 사용한 후에는 스트림을 재사용할 수 없습니다.
- 즉 스트림을 사용했다면 다시 스트림을 생성해야 한다.
- 기존 데이터 수정 없음: 스트림 작업은 원본 데이터를 변경하지 않습니다.
- 별도의 메모리 공간: 스트림이 사용하는 메모리 공간은 원본 데이터와 별도로 생성됩니다.
- 중간 및 최종 작업: 스트림 작업은 중간 및 최종 작업으로 나뉩니다.
- Lazy Operation: 중간 작업의 결과는 최종 작업이 수행될 때까지 알 수 없습니다.
예시 : 스트림 생성 및 사용 방법
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// Stream
Stream<Integer> numberStream = numbers.stream();
// Processing
Stream<Integer> processedStream = numberStream.filter(n -> n % 2 == 0) // Filter even numbers
.map(n -> n * n); // Square each number
// Collection
List<Integer> result = processedStream.collect(Collectors.toList());
System.out.println(result); // Prints: [4, 16, 36, 64, 100]
- 스트림:
- 먼저
stream()
메서드를 사용하여 정수 목록에서 스트림을 만듭니다. - 이렇게 하면 병렬로 처리할 수 있는 일련의 요소가 생성됩니다.
- 먼저
- 처리
- 그런 다음
filter()
메서드를 사용하여 짝수만 필터링하고map()
메서드를 사용하여 각 숫자를 제곱합니다. - 작업은 즉시 수행되지 않고 데이터가 실제로 필요할 때 나중에 수행되도록 대기합니다(이를 "지연 평가"라고 함).
- 그런 다음
- 수집
- 마지막으로
collect()
메서드를 사용하여 결과를 다시 목록으로 변환합니다. - 이 시점에서 대기 중인 모든 작업이 수행되고 데이터가 처리됩니다.
- 마지막으로
중간 연산과 최종 연산
중간 연산
중간 연산은 스트림 요소에서 데이터 변환 및 필터링을 수행하지만 최종 결과를 생성하지는 않습니다.
대신 추가 중간 연산이나 터미널 연산으로 추가 처리할 수 있는 새 스트림을 반환합니다.
- filter(): 특정 조건을 충족하는 요소 추출
- map(): 지정된 함수에 따라 각 요소 변환
- sorted(): 스트림의 요소를 특정 순서로 정렬합니다.
최종 연산
forEach(), count(), sum()과 같은 터미널(또는 최종) 연산은 스트림을 처리하여 콘솔에 출력을 인쇄하거나 데이터베이스에 데이터를 저장하는 등의 최종 결과를 생산합니다
- forEach(): 스트림의 각 요소에 대해 작업을 수행합니다.
- count(): 스트림의 요소 개수 반환
- sum(): 스트림에 있는 요소의 합을 계산합니다.
터미널 연산은 중간 연산 처리를 트리거하고 스트림이 종료되므로 해당 스트림에서 더 이상 연산을 수행할 수 없다는 점에 유의해야 합니다.
예제 코드
sList.stream().filter(s->s.length() >= 5).forEach(s->System.out.println(s));
customerList.stream().map(c->c.getName()).forEach(s->System.out.println(s));
중간 연산과 최종 연산에 대한 구현은 주로 람다식을 활용합니다
public class IntArrayStreamTest {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
Arrays.stream(arr).forEach(n->System.out.print(n + "\t"));
System.out.println();
int sum = Arrays.stream(arr).sum();
System.out.println("sum: " + sum);
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
int sum2 = list.stream().mapToInt(n->n.intValue()).sum();
System.out.println(sum2);
}
}
위의 코드를 보면 새로운 연산을 위해서 list로부터 스트림을 다시 재생산하는 것을 볼 수 있습니다.
부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>
728x90
'DEV > Java' 카테고리의 다른 글
Java의 예외처리 - 🐥 카카오 테크 캠퍼스 (0) | 2023.05.03 |
---|---|
Java의 Reduce - 🐥 카카오 테크 캠퍼스 (0) | 2023.05.02 |
Java의 Lambda - 🐥 카카오 테크 캠퍼스 (0) | 2023.05.02 |
Java의 내부 클래스 - 🐥 카카오 테크 캠퍼스 (0) | 2023.05.02 |
Interface의 활용 - 🐥 카카오 테크 캠퍼스 (0) | 2023.04.28 |