이전에 혼자서 자바를 공부할 때에도 스트림을 한 번 학습한 적이 있고
코딩테스트 문제를 풀면 해당 문제에 대한 다른 사람들의 풀이를 볼 수 있는데 거기에서 스트림으로만 문제를 푸는 사람을 보고
스트림을 제대로 공부하면 재밌겠다 생각은 했지만 실행은 못 하고 있었다.
그렇게 스트림에 대한 관심이 없어져 있었는데 오늘 수업에서 스트림을 학습하며
제대로는 아니더라도 조금 디테일하게 알아보고 싶다고 생각이 들었다.
스트림(Stream)이란?
- 람다를 활용해 배열과 컬렉션을 함수형으로 간단하게 처리할 수 있는 기술
- 기존의 배열이나 컬렉션에 저장된 데이터에 접근하려면 반복문, iterator를 사용해야 했지만 이런 문제를 극복해줌
스트림 특징
- 스트림은 데이터 소스를 변경하지 않는다.
- 스트림은 데이터를 그대로 둔 채, 필요한 연산을 해서 새로운 결과만 만들어낸다.
- 스트림은 재사용 할 수 없다.
- 스트림은 한 번 사용하면 소모되어 다시 다른 연산에 사용하는 것이 불가능하다.
- 스트림은 자료의 대상과 상관 없이 동일한 연산을 수행한다.
- 배열이나 컬렉션은 데이터 소스마다 다른 방식으로 다뤄야 한다.
- 스트림을 사용하면 모두 일관된 방법으로 다룰 수 있다.
- 최종 연산 전까지 중간 연산을 수행하지 않는다.
스트림 사용 절차
1. 스트림 생성
- 배열 스트림 - Arrays.stream()
int[] arr = new int[]{12, 21, 88, 8, 18};
//1
IntStream stream = Arrays.stream(arr);
//2
Stream<Integer> stream = Arrays.stream(arr).boxed();
- Collection 스트림 - stream()
Set<Integer> set = Set.of(14, 145, 647);
Stream<Integer> stream = set.stream();
- Stream.builder()
Stream<String> stream = Stream.<String>builder()
.add("A")
.add("B")
.add("C")
.build();
- 기본 타입
int[] arr = {12, 21, 88, 8, 18};
IntStream stream = Arrays.stream(arr);
2. 중간 연산
- filter : 스트림의 요소들을 하나씩 조건에 따라 필터링( = if )
List<Integer> list = List.of(10, 15, 20, 25, 30);
list.stream()
.filter(n -> n >= 20)
.forEach(System.out::println);
//출력 : 20, 25, 30
- map : 스트림의 요소들을 특정 값으로 변환, 람다를 매개변수로 받아 값을 변환
- 스트림을 원하는 형태로 변환할 때 사용
List<String> list = List.of("java", "python", "spring");
list.stream()
.map(String::toUpperCase)
.forEach(System.out::println);
//출력 : JAVA, PYTHON, SPRING
- sorted : 스트림의 요소들을 정렬, Comparator 사용
List<Integer> list = List.of(30, 10, 20);
list.stream()
.sorted()
.forEach(System.out::println);
//출력 : 10, 20, 30
- 연결 : 중간 연산은 여러 개를 연결할 수 있다.
books.stream()
.filter(b -> b.getPrice() >= 20000) // 중간연산
.sorted(Comparator.comparing(Book::getPrice)) // 중간연산
.map(Book::getName) // 중간연산
.forEach(System.out::println);
3. 최종 연산
- forEach : 요소 소비
books.stream()
.filter(b -> b.getPrice() >= 20000)
.sorted(Comparator.comparing(Book::getPrice))
.map(Book::getName)
.forEach(System.out::println);
- collect : 결과를 원하는 자료형으로 수집
List<String> result = books.stream()
.filter(b -> b.getPrice() >= 20000)
.map(Book::getName)
.collect(Collectors.toList());
Set<String> result = books.stream()
.map(Book::getName)
.collect(Collectors.toSet());
- 계산
List<Integer> list = List.of(10, 20, 30);
long count = list.stream().count();
int sum = list.stream().mapToInt(Integer::intValue).sum();
int min = list.stream().mapToInt(Integer::intValue).min().getAsInt();
int max = list.stream().mapToInt(Integer::intValue).max().getAsInt();
double avg = list.stream().mapToInt(Integer::intValue).average().getAsDouble();
- anyMatch : 조건 검사
boolean result = books.stream()
.anyMatch(b -> b.getPrice() >= 30000);
System.out.println(result);
느낀 점
이렇게 오늘은 자바의 스트림에 대해 학습한 것을 바탕으로 추가적으로 검색도 하면서 정리를 해봤다.
위에서 말했듯이 스트림을 제대로 공부해보고 싶었던 마음이 있었는데 강의에서 강사님이 말씀하시길 실무에서 쓰이는 경우는 거의 없다고 하셔서 많이 아쉬웠다.. 하지만 알아둬서 나쁠 건 없다고 생각했기 때문에 정리를 시작했다.
TIL을 작성하면서 스트림을 사용하는 절차도 보고 예시들도 보는데 개인적으로는 문법이라던지 표현이 직관적으로 바로 와닿지는 않는 것 같다.
그래도 제대로 알고 있으면 코딩테스트 문제를 풀 때나 혼자서 학습을 할 때 도움이 될 거라 믿고 복습도 하고 더 알아보기도 할 예정이다.
'AIBE5 TIL' 카테고리의 다른 글
| [TIL 26/03/04](DB) GROUP BY (0) | 2026.03.04 |
|---|---|
| [TIL 26/02/11](Java) hashCode(), equals() 오버라이딩 (0) | 2026.02.11 |
| [TIL 26/02/10](Java) 인터페이스 (0) | 2026.02.10 |
| [TIL 26/02/09](Java) 상속 (0) | 2026.02.09 |
| [TIL 26/02/06](Java) 접근제어자와 캡슐화 (0) | 2026.02.06 |