
자바 공부 중 스트림을 배우면서
람다식, :: 메서드 참조, IntStream, collect() 등
처음 보는 기능들이 많이 나왔다.
이번 글에서는 내가 헷갈렸던 부분들을 중심으로 정리해보려고 한다.
스트림에서 자주 보이는 문법:
users.stream()
.map(User::getName)
.forEach(System.out::println);
이게 처음에는 굉장히 신기했다.
:: 는 람다식을 더 간결하게 표현한 문법이다.
예를 들어:
user -> user.getName()
는
User::getName
로 줄일 수 있다.
.map(User::getName)
은 사실 이렇게 해석된다:
.map(user -> user.getName())
스트림이 Function<User, String> 형태를 요구하고,
getName() 이 그 시그니처와 일치하기 때문에 연결되는 것이다.
System.out::println 의 의미.forEach(System.out::println);
이건
.forEach(name -> System.out.println(name));
과 동일하다.
System.out 은 PrintStream 객체이고,
그 객체의 println() 메서드를 Consumer<T> 형태로 전달한 것이다.
메서드 참조는
함수형 인터페이스의 추상 메서드 시그니처와
일치하는 메서드를 자동 연결하는 문법
이다.
스트림에는 두 종류가 있다.
Stream<T>
예:
- Stream<String>
- Stream<User>
- Stream<Integer>
이건 primitive 전용이다.
IntStream.range(0, 10)
→ 0 ~ 9 까지 숫자 스트림 생성
IntStream.rangeClosed(1, 10)
→ 1 ~ 10 포함
IntStream.range(0, 10).max();
IntStream.range(0, 10).min();
IntStream.range(0, 10).sum();
여기서 중요한 점은:
sum(), max(), min() 은 IntStream 전용 기능이다.
예제:
int totalAge = users.stream()
.mapToInt(user -> user.getAge())
.sum();
users.stream()
.map(user -> user.getAge());
이건
Stream<Integer>
가 된다.
하지만 Stream<Integer> 에는 .sum() 이 없다
.mapToInt(user -> user.getAge())
이건
Stream<User> → IntStream
으로 변환하는 과정이다.
그 다음 .sum() 이 가능해진다.
String result = datas1.stream()
.map(String::valueOf)
.collect(Collectors.joining(", "));
이건
1, 2, 3, 4
형태로 문자열을 합쳐준다.
스트림의 최종 연산이다.
스트림 결과를 원하는 자료형으로 모아주는 역할
예:
Collectors.toList()Collectors.joining()Collectors.groupingBy()예제:
data.chars()
.map(c -> c + 32)
.mapToObj(c -> (char)c)
String → IntStream
문자는 내부적으로 숫자(Unicode 코드값) 이기 때문이다.
IntStream → Stream<T>
즉, 기본형 스트림을 객체 스트림으로 변환하는 메서드이다.
IntStream 의 map() 은
int → int
만 가능하다.
객체로 변환하려면 반드시 mapToObj() 를 사용해야 한다.
Stream<User>
↓ mapToInt
IntStream
↓ sum
int 결과
String
↓ chars()
IntStream
↓ map()
IntStream
↓ mapToObj()
Stream<Character>
↓ collect()
String
✔ :: 는 람다식을 줄인 메서드 참조
✔ IntStream 은 primitive 전용 스트림
✔ sum(), max() 는 IntStream 전용
✔ mapToInt 는 객체 스트림 → 기본형 스트림 변환
✔ mapToObj 는 기본형 스트림 → 객체 스트림 변환
✔ collect 는 스트림을 최종 결과로 모으는 연산
스트림은 단순히 "반복문 줄이기" 가 아니라,
데이터를 흐름처럼 단계별로 변환하는 구조
라는 걸 이번에 확실히 이해하게 되었다.
스트림은 반복문을 감추는 기술이 아니라,
데이터의 흐름을 함수처럼 다루는 구조다.