Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Websocket
- 1px border
- github
- ES5
- 서버리스 #
- font-size
- TS
- 클론코딩
- 0.5px border
- &연산
- 으
- 컴포넌튼
- 당근마켓
- ZOOM
- npm
- TypeScript
- Props
- 전역변수
- 0.25px border
- 데이터베이스 #try #이중
- jwt
- 10px
- es6
- Strict
- angular
- 0.75px border
- literal
- 문서번호
- entity
- 타입스크립트
Archives
- Today
- Total
복잡한뇌구조마냥
[JAVA] 스트림 ( Stream ) 본문
✅ 개요
Java 8부터 도입된 Stream은 데이터를 선언형 방식으로 처리할 수 있는 기능입니다.
기존의 for-loop 방식보다 간결하고 가독성이 높으며, 병렬 처리도 간편하게 할 수 있어 자바 개발자라면 꼭 익혀야 할 기능입니다.
🔍 1. Stream이란?
Stream은 데이터의 흐름(데이터 스트림)을 추상화한 개념입니다.
컬렉션(List, Set 등)을 반복하거나 필터링/변환할 때, 스트림 API를 사용하면 더 선언적이고 간결한 코드를 작성할 수 있습니다.
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println); // 출력: Alice
🔧 2. Stream 사용 구조
collection.stream()
.중간연산1()
.중간연산2()
...
.최종연산();
- 중간 연산: filter(), map(), sorted() 등 → 스트림을 변환 (lazy 연산)
- 최종 연산: forEach(), collect(), count(), reduce() 등 → 결과를 반환
📌 Stream은 lazy하기 때문에 최종 연산을 호출해야 중간 연산이 실행됩니다.
🛠️ 3. 주요 연산 예시
🔸 filter(): 조건에 맞는 요소만 필터링
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println); // 2, 4
🔸 map(): 요소 변환
List<String> names = List.of("kim", "lee", "park");
names.stream().map(String::toUpperCase).forEach(System.out::println);
🔸 sorted(): 정렬
List<String> names = List.of("banana", "apple", "cherry");
names.stream().sorted().forEach(System.out::println);
🔸 collect(): 결과 수집 (List 등으로)
List<String> filtered = names.stream()
.filter(name -> name.length() <= 3)
.collect(Collectors.toList());
🔸 reduce(): 누적 계산
int sum = List.of(1, 2, 3, 4).stream()
.reduce(0, Integer::sum); // 10
⚙️ 4. 병렬 처리 (parallelStream)
list.parallelStream()
.map(...)
.forEach(...);
- 내부적으로 Fork/Join 프레임워크 사용
- 대용량 데이터 처리 시 유용하지만, 무조건 빠르지는 않음 → 병렬 처리 오버헤드 고려해야 함
🧠 5. Stream 사용 시 주의할 점
항목 | 주의사항 |
스트림 재사용 | 한 번 소비되면 재사용 불가 (새로 얻어야 함) |
상태 있는 연산 | peek() 같은 연산은 디버깅 외에는 주의 |
성능 | 소규모 데이터엔 오히려 for문보다 느릴 수 있음 |
Null 처리 | NPE 방지를 위해 Optional과 함께 쓰면 좋음 |
📦 6. 실전 예제: 객체 리스트 필터링 및 정렬
class User {
String name;
int age;
// 생성자, getter 생략
}
List<User> users = List.of(
new User("Alice", 25),
new User("Bob", 18),
new User("Charlie", 30)
);
List<String> adultNames = users.stream()
.filter(user -> user.age >= 20)
.sorted(Comparator.comparingInt(user -> user.age))
.map(user -> user.name)
.collect(Collectors.toList());
결과: ["Alice", "Charlie"]
🧩 7. Stream vs 기존 반복문
기준 | for-loop | Stream |
코드 길이 | 길어짐 | 간결 |
가독성 | 낮음 | 높음 |
병렬 처리 | 복잡 | 쉬움 (parallelStream) |
디버깅 | 쉬움 | 어렵기도 함 (중간 연산 추적 어려움) |
✍️ 마무리
Java Stream은 선언형 프로그래밍의 핵심 기능으로, 많은 반복문 로직을 간결하게 바꿀 수 있는 도구입니다.
하지만 모든 경우에 Stream이 정답은 아니며, 적절한 상황에서 for문과 병행해서 쓰는 것이 좋습니다.
“Stream을 이해하면 코드가 간결해지고, 오히려 더 깊은 객체지향적 사고로 나아갈 수 있다.”
LIST
'BE > JAVA' 카테고리의 다른 글
[JAVA] 반복문 간결하게 쓰는 법 - 람다와 메서드 참조로 리팩토링 (2) | 2025.07.29 |
---|---|
[JAVA] 구성 ( Composition ) (0) | 2025.07.29 |
[JAVA] 자주 사용하는 자료형 핵심 메소드 정리 (1) | 2025.07.14 |
[JAVA] n진수 변환, 변환 정리 (String ↔ 숫자형) + 3진법 뒤집기 (0) | 2025.07.03 |
[JAVA] 람다 ( 람다식 ) (0) | 2025.06.18 |