# Java Stream
Java의 Stream은 데이터 처리 방식을 간결하게 만들기 위해 도입된 기능으로 원본 데이터를 변경하지 않고 별도의 메모리에서 동작한다.
주로 Collection(List, Set 등)을 대상으로 사용되며 선언형 스타일로 데이터를 처리할 수 있다.
# Stream의 구조
Stream은 크게 세 단계로 구성된다.
1) 생성 (Create)
배열 또는 컬렉션에서 스트림을 만든다.
2) 중간 연산 (Intermediate Operation)
원하는 방식으로 가공한다.
대표 연산: map, filter, sorted 등
→ 여러 번 이어 붙일 수 있음
→ 중간연산은 Lazy, 즉 최종연산이 실행될 때 실제로 동작한다.
3) 최종 연산 (Terminal Operation)
결과를 만든다.
대표 연산: forEach, reduce, collect, sum, count
# Stream의 특징
원본을 보존한 채 별도의 메모리에서 처리된다.
한 번 사용하면 닫힌다(재사용 불가) → 필요하면 새로 만들기
중간 연산은 누적, 최종 연산에서 실행
# Stream 기본 예시
int arr[] = {1, 2, 3, 4, 5};
// stream 생성
IntStream intStream = Arrays.stream(arr);
System.out.println(intStream.sum()); // 최종연산(sum)
한 번 최종연산을 하면 스트림은 닫힌다.
intStream = Arrays.stream(arr); // 다시 생성
System.out.println(intStream.sum());
최댓값도 Optional 형태로 받을 수 있다.
OptionalInt oi = Arrays.stream(arr).max();
oi.ifPresent(System.out::println);
# 중간 연산 활용 (map, filter)
List<String> animalList = Arrays.asList(
"Animal", "Cat", "Tiger", "Superman", "Human"
);
// 길이 평균
animalList.stream()
.mapToInt(String::length)
.average()
.ifPresent(System.out::println);
// man으로 끝나는 단어 길이 출력
animalList.stream()
.filter(s -> s.endsWith("man"))
.map(String::length)
.forEach(System.out::println);
조건부 필터링 후 리스트로 만들기
List<String> manList = animalList.stream()
.filter(s -> s.endsWith("man"))
.filter(s -> s.length() >= 5)
.collect(Collectors.toList());
# Stream 실전 예제 — Car 리스트 가공하기
아래처럼 Car 객체 리스트가 있다고 가정한다.
List<Car> cars = Arrays.asList(
new Car(1L, "LG", "L-202", "w", 1992, 3000),
new Car(2L, "LG-1", "L-101", "w", 1992, 1000),
new Car(3L, "SMS", "SM-202", "r", 1999, 2000),
new Car(4L, "LG-4", "L-102", "r", 1995, 1000),
new Car(5L, "LG-5", "L-205", "w", 1995, 100)
);
1) 가격이 2500 이하인 차량의 브랜드만 출력
cars.stream()
.filter(car -> car.getPrice() <= 2500)
.map(Car::getBrand)
.forEach(System.out::println);
2) 브랜드가 LG로 시작하는 차량 가격을 500원 인상
cars.stream()
.filter(car -> car.getBrand().startsWith("LG"))
.map(car -> {
car.setPrice(car.getPrice() + 500);
return car;
})
.forEach(System.out::println);
3) 연식이 1995 이상인 차량을 가격순 정렬
cars.stream()
.filter(car -> car.getDateYear() >= 1995)
.sorted(Comparator.comparingInt(Car::getPrice))
.forEach(System.out::println);
4) 차량 가격 총합
int totalPrice = cars.stream()
.mapToInt(Car::getPrice)
.sum();
System.out.println(totalPrice);
5) 특정 컬러(예: r) 차량 개수
long countR = cars.stream()
.filter(car -> car.getColor().equals("r"))
.count();
System.out.println(countR);
6) 가격 < 2000 AND 색상 = w 조건의 차량 목록
cars.stream()
.filter(car -> car.getPrice() < 2000)
.filter(car -> car.getColor().equals("w"))
.forEach(System.out::println);
7) 색상이 w인 차량을 가격순 정렬해 출력
cars.stream()
.filter(car -> car.getColor().equals("w"))
.sorted(Comparator.comparingInt(Car::getPrice))
.forEach(System.out::println);
| 구분 | 역할 |
| Stream 생성 | 배열·컬렉션을 스트림으로 변환 |
| 중간연산(map, filter, sorted, …) | 데이터를 원하는 형태로 가공 |
| 최종연산(forEach, reduce, collect, …) | 결과를 만들고 스트림 종료 |
'java' 카테고리의 다른 글
| Thread (0) | 2025.11.28 |
|---|---|
| Lambda Expression(=람다식) (0) | 2025.11.28 |
| Generic Type(=제네릭 타입) (0) | 2025.11.28 |
| Abstract class(=추상화) (0) | 2025.11.28 |
| Encapsulation(=캡슐화) (0) | 2025.11.28 |
