Java 8에서 도입된 가장 큰 변화 중 하나는 함수형 프로그래밍 스타일의 도입이다. 그 중심에는 람다식(Lambda Expression)과 스트림 API(Stream API)가 존재한다. 람다식을 통해 코드를 더욱 간결하고 직관적으로 작성할 수 있게 되었으며, 스트림을 사용하면 컬렉션이나 배열 데이터를 효율적이고 통일된 방식으로 처리할 수 있다.
람다식은 익명 함수(Anonymous Function)를 생성하기 위한 식이다. 메서드를 하나의 간결한 '식(Expression)'으로 표현하여 코드를 줄이고 가독성을 높여준다.
(매개변수) -> { 실행문; }Runnable, Supplier, Consumer, Function, Predicate 등이 있다.// 기존 익명 클래스 방식
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
// 람다식 적용
Runnable runnable2 = () -> System.out.println("Hello World!");
스트림은 데이터 소스(컬렉션, 배열 등)를 추상화하고, 데이터를 다루는 데 자주 사용되는 메서드들을 정의해 둔 객체다.
주요 특징:
parallelStream()을 활용하면 다중 스레드를 통한 병렬 처리를 손쉽게 구현할 수 있다.스트림을 이용한 데이터 처리는 생성 -> 중간 연산 -> 최종 연산의 흐름(파이프라인)을 거친다.
컬렉션이나 배열 등을 스트림 객체로 변환하는 단계다.
list.stream() / Arrays.stream(array) / Stream.of(...)데이터를 가공·필터링하는 단계로, 연산 결과로 새로운 스트림을 반환하므로 체이닝(Chaining)이 가능하다. 최종 연산이 호출되기 전까지는 실행되지 않는 지연 연산(Lazy Evaluation)의 특징을 갖는다.
filter(Predicate): 조건에 맞는 요소만 추출map(Function): 요소를 원하는 형태나 값으로 변환flatMap(Function): 중첩된 구조(리스트 안의 리스트 등)를 단일 스트림으로 평평하게 변환distinct(): 중복 요소 제거 (equals, hashCode 기준)sorted() / sorted(Comparator): 요소 오름차순 또는 지정 기준 정렬limit(long maxSize): 지정한 개수만큼 요소 잘라내기skip(long n): 지정한 개수만큼 요소 건너뛰기peek(Consumer): 중간 결과 확인 (디버깅 용도)가공된 스트림의 요소를 소모하여 최종 결과를 도출한다. 최종 연산이 실행되면 스트림 파이프라인이 닫히며 재사용할 수 없다.
collect(Collector): List, Set, Map 등 원하는 컬렉션 타입으로 결과 수집forEach(Consumer): 각 요소를 순회하며 지정된 작업 수행toArray(): 스트림 요소를 배열로 변환count(): 전체 요소 개수 반환sum() / average(): 숫자형 스트림의 합계 및 평균 계산max(Comparator) / min(Comparator): 최댓값 및 최솟값 반환 (Optional)reduce(BinaryOperator): 모든 요소를 누적하여 하나의 결과로 축소anyMatch(Predicate): 조건에 맞는 요소가 하나라도 있는지 확인 (boolean)allMatch(Predicate): 모든 요소가 조건을 만족하는지 확인 (boolean)noneMatch(Predicate): 모든 요소가 조건을 만족하지 않는지 확인 (boolean)findFirst() / findAny(): 조건에 맞는 첫 번째 또는 임의의 요소 반환 (Optional)List<String> names = Arrays.asList("Kim", "Lee", "Park", "Kang");
// 이름이 'K'로 시작하는 요소를 필터링하여 대문자로 변환 후 리스트로 수집
List<String> kNames = names.stream()
.filter(name -> name.startsWith("K")) // 중간 연산
.map(String::toUpperCase) // 중간 연산
.collect(Collectors.toList()); // 최종 연산
for, while)과 조건문(if)이 복잡하게 얽힌 코드를 단 몇 줄의 직관적인 체이닝 코드로 대체할 수 있다.자바의 람다와 스트림은 코드를 훨씬 간결하고 가독성 있게 만들어 주는 강력한 도구다. 람다식은 함수형 프로그래밍의 기반을 제공하며, 스트림은 데이터 처리 파이프라인(생성-중간연산-최종연산)을 통해 데이터의 가공 및 집계를 손쉽게 처리하도록 돕는다.