함수형 인터페이스, 람다식, 메서드 참조, Stream과 Optional을 다룬다.
람다와 스트림
람다와 스트림은 데이터를 다루는 코드를 짧고 선언적으로 만들어 줍니다. "어떻게 반복할지"를 일일이 적는 대신 "무엇을 하고 싶은지"를 표현하는 방식입니다. 데이터를 거르고, 변환하고, 모으는 작업이 한결 간결해집니다.
학습 목표
- 함수형 인터페이스와 람다식을 이해한다.
- 메서드 참조를 사용한다.
Stream의filter,map,collect로 데이터를 처리한다.Optional로 null을 안전하게 다룬다.
함수형 인터페이스와 람다식
추상 메서드가 하나뿐인 인터페이스를 함수형 인터페이스라 합니다. 이를 람다식으로 간단히 구현할 수 있습니다.
// 기존 방식
Runnable r1 = new Runnable() {
public void run() {
System.out.println("실행");
}
};
// 람다식
Runnable r2 = () -> System.out.println("실행");
람다는 (매개변수) -> 동작 형태입니다.
import java.util.function.Function;
Function<Integer, Integer> square = x -> x * x;
System.out.println(square.apply(5)); // 25
💡 TIP —
Function,Predicate(조건 검사),Consumer(소비),Supplier(공급)는 자바가 미리 제공하는 대표적인 함수형 인터페이스입니다.
메서드 참조
람다가 단순히 기존 메서드를 호출하기만 한다면 클래스::메서드 형태로 더 짧게 쓸 수 있습니다.
List<String> names = List.of("kim", "lee", "park");
names.forEach(s -> System.out.println(s)); // 람다
names.forEach(System.out::println); // 메서드 참조
Stream의 기본
Stream은 컬렉션의 데이터를 흐름처럼 처리합니다. 중간 연산(filter, map)으로 가공하고 최종 연산(collect, forEach)으로 결과를 얻습니다.
import java.util.List;
import java.util.stream.Collectors;
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6);
List<Integer> evenSquares = numbers.stream()
.filter(n -> n % 2 == 0) // 짝수만
.map(n -> n * n) // 제곱으로 변환
.collect(Collectors.toList());
System.out.println(evenSquares); // [4, 16, 36]
filter는 조건에 맞는 것만 남기고, map은 각 요소를 변환하며, collect는 결과를 리스트 등으로 모읍니다.
⚠️ 주의 — 스트림은 한 번 최종 연산을 하면 다시 사용할 수 없습니다. 같은 데이터를 또 처리하려면 스트림을 새로 만들어야 합니다.
자주 쓰는 스트림 연산
List<String> names = List.of("kim", "lee", "park", "kang");
long count = names.stream()
.filter(s -> s.length() == 3)
.count(); // 3
List<String> upper = names.stream()
.map(String::toUpperCase)
.collect(Collectors.toList()); // [KIM, LEE, PARK, KANG]
int total = List.of(1, 2, 3).stream()
.mapToInt(Integer::intValue)
.sum(); // 6
Optional
Optional은 값이 있을 수도 없을 수도 있음을 표현해 null 처리를 안전하게 합니다.
import java.util.Optional;
Optional<String> result = List.of("a", "b", "c").stream()
.filter(s -> s.equals("b"))
.findFirst();
System.out.println(result.orElse("없음")); // b
Optional<String> empty = Optional.empty();
System.out.println(empty.orElse("기본값")); // 기본값
orElse로 값이 없을 때의 기본값을 정하면 NullPointerException을 피할 수 있습니다.
요약
- 함수형 인터페이스는 추상 메서드가 하나이며 람다식으로 구현합니다.
- 람다는
(매개변수) -> 동작, 메서드 참조는클래스::메서드형태입니다. Stream은filter로 거르고map으로 변환하며collect로 모읍니다.- 스트림은 한 번 소비하면 재사용할 수 없습니다.
Optional로 값의 부재를 안전하게 표현하고orElse로 기본값을 줍니다.
연습문제
x -> x + 1을 하는Function<Integer, Integer>람다를 만들어 호출하세요.- 리스트
[1,2,3,4,5,6]에서 3보다 큰 수만 걸러 출력하세요. - 문자열 리스트를 모두 대문자로 변환해 새 리스트로 모으세요.
- 리스트에서 "target"을 찾아
Optional로 받고, 없으면 "없음"을 출력하세요.
힌트 —
filter후collect, 찾기는findFirst()를 사용합니다.
💡 연습문제 풀이
불러오는 중…
댓글 0
“Java” 강좌에 대한 댓글입니다.