일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- kotlin
- 오블완
- 널 허용
- 코틀린
- 이메일 본인인증
- string.repeat()
- entity
- Spring Boot
- 자바
- jpa repository
- 복합 키
- 스프링 부트
- ispresent
- 티스토리챌린지
- javamailsender
- 토큰
- 객체지향
- JPQL
- map
- @embededid
- Spring
- string?
- java
- mutablemap
- Token
- devpi
- 스프링
- JPA
- email api 구현
- embededid
- Today
- Total
DeveloPiano
[Java] Stream 으로 간결하고 효율적인 데이터 처리하기 본문
Java 8에서 도입된 Stream API는 데이터를 처리하고 변환하는 방식을 혁신적으로 개선했습니다. 컬렉션이나 배열의 데이터를 함수형 프로그래밍 스타일로 처리할 수 있도록 지원하며, 복잡한 데이터 처리 로직을 간결하고 직관적으로 구현할 수 있게 합니다. 이번 포스트에서는 Java Stream의 개념과 주요 기능을 살펴보고, 다양한 예시를 통해 어떻게 활용할 수 있는지 알아보겠습니다.
Java Stream이란?
Java Stream은 데이터 소스의 요소들을 추상화하여 일련의 연산(필터링, 매핑, 집계 등)을 처리할 수 있는 API입니다. 스트림을 사용하면 반복문 없이 선언적이고 함수형 프로그래밍 스타일로 데이터를 처리할 수 있습니다. 예를 들어, 리스트의 요소를 필터링하거나, 맵핑하여 변환하고, 집계하는 작업 등을 손쉽게 구현할 수 있습니다.
Java Stream의 주요 특징
- 선언적 스타일 : 스트림을 사용하면 반복문 없이 고차 함수(filter, map, reduce 등)를 사용하여 선언적으로 코드를 작성할 수 있습니다.
- 함수형 프로그래밍 : 람다 표현식과 함께 사용하여 간결하고 가독성 높은 코드를 작성할 수 있습니다.
- 지연 처리(Lazy Evaluation) : 스트림 연산은 필요할 때만 수행되므로 성능 최적화를 도와줍니다.
- 병렬 처리 : 병렬 스트림을 사용하면 멀티코어 프로세서를 활용한 병렬 처리가 가능합니다.
스트림의 구조
스트림은 데이터 처리 작업을 세 가지 단계로 나눕니다:
- 생성 : 스트림을 데이터 소스(컬렉션, 배열, I/O 등)로부터 생성합니다.
- 중간 연산 : 스트림을 변환하거나 필터링하는 연산으로, 이 단계에서는 새로운 스트림이 생성됩니다. 중간 연산은 지연되어 필요할 때 실행됩니다.
- 종결 연산 : 스트림의 최종 결과를 도출하는 연산입니다. 종결 연산이 호출되면 스트림은 소비되고 더 이상 사용할 수 없습니다.
Java Stream 사용 예시
Java Stream은 간단한 작업부터 복잡한 데이터 변환까지 다양한 시나리오에서 활용할 수 있습니다. 아래 예시를 통해 Java Stream의 기본적인 사용법을 알아봅시다.
1. 리스트에서 짝수만 필터링하여 출력하기
스트림을 사용하여 리스트에서 짝수만 필터링하고 출력하는 간단한 예시입니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numbers.stream() // 스트림 생성
.filter(n -> n % 2 == 0) // 중간 연산: 필터링
.forEach(System.out::println); // 종결 연산: 출력
}
}
위 코드는 filter 중간 연산을 사용하여 짝수만을 필터링하고, forEach 종결 연산을 통해 결과를 출력합니다.
2. 문자열 리스트를 대문자로 변환하고 정렬하기
문자열 리스트의 모든 요소를 대문자로 변환하고 정렬하는 예시입니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<String> names = Arrays.asList("alice", "bob", "charlie", "david");
names.stream()
.map(String::toUpperCase) // 중간 연산: 대문자로 변환
.sorted() // 중간 연산: 정렬
.forEach(System.out::println); // 종결 연산: 출력
}
}
map 중간 연산을 통해 문자열을 대문자로 변환하고, sorted 중간 연산으로 알파벳 순서대로 정렬합니다.
3. 리스트의 숫자 합계 계산
스트림을 사용하여 리스트의 숫자를 모두 더하는 방법입니다.
import java.util.Arrays;
import java.util.List;
public class StreamExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
.reduce(0, Integer::sum); // 종결 연산: 합계 계산
System.out.println("Sum: " + sum);
}
}
Java Stream의 주요 연산들
Java Stream에서 자주 사용되는 주요 연산들을 소개합니다. 스트림의 연산은 크게 중간 연산과 종결 연산으로 나뉩니다.
주요 중간 연산
- filter(Predicate<T> predicate) : 조건에 맞는 요소만 선택합니다.
- map(Function<T, R> mapper) : 요소를 다른 형태로 변환합니다.
- sorted(Comparator<T> comparator) : 요소를 정렬합니다.
- distinct() : 중복된 요소를 제거합니다.
- limit(long maxSize) : 요소의 개수를 제한합니다.
- skip(long n) : 처음 n개의 요소를 건너뜁니다.
주요 종결 연산
- forEach(Consumer<T> action) : 각 요소에 대해 작업을 수행합니다.
- collect(Collector<T, A, R> collector) : 스트림의 결과를 컬렉션, 리스트, 맵 등으로 변환합니다.
- reduce(BinaryOperator<T> accumulator) : 요소를 하나의 값으로 줄입니다.
- count() : 요소의 개수를 반환합니다.
- anyMatch(Predicate<T> predicate), allMatch(Predicate<T> predicate), noneMatch(Predicate<T> predicate) : 조건에 따른 요소 검사
마무리
Java Stream은 데이터를 다루는 방식을 간결하고 효율적으로 만들어주는 강력한 기능입니다. 스트림을 사용하면 데이터 처리가 더욱 직관적이고 선언적으로 이루어지며, 성능 최적화와 병렬 처리의 이점을 누릴 수 있습니다. 이번 포스트에서는 Java Stream의 개념과 주요 기능을 살펴보았는데요, 이를 활용하여 더 읽기 쉽고 유지 관리가 쉬운 코드를 작성해 보세요!
'Develop > Java' 카테고리의 다른 글
[Java] MapStruct로 간편하게 객체 매핑하기 (1) | 2024.09.23 |
---|---|
[Java] Optional과 List의 상관관계 : isEmpty(), isPresent()의 차이와 동작 원리 (2) | 2024.09.18 |
[Java] 이메일 인증 기반 회원가입 API 구현하기 (0) | 2024.09.03 |
[Java] Spring Boot 활용 Email 발송하기 (1) | 2024.09.02 |
[Java] StringUtils 사용의 장점 (0) | 2024.08.20 |