Java 8부터 사용할 수 있는 람다(lamda) 표현식은 주로 함수형 인터페이스를 구현하는데 사용된다.
예를 들면 아래와 같이 람다를 활용하면 별도의 클래스를 작성하지 않고 일회성으로
Runnable 인터페이스의 기본적인 함수인 run() 메소드를 오버라이딩하여 일회용 구현체(?) 같은 느낌으로 작성할 수 있다.
1. 람다 표현식을 활용한 인터페이스 메소드 구현
Runnable runnable = () - > System.out.println(" I'm running in a Thread ");
new Thread(runnable).start();
2. 람다 표현식을 활용한 리스트 정렬
List<String> names = Arrays.asList("mimi", "nanan", "BBo");
names.sort(Comparator.naturalOrder());
names.forEach(System.out::println);
3. 람다 표현식 + Stream을 활용한 리스트 데이터 처리
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
numbers.stream()
.filter(n -> n % 2 ==0)
.forEach(System.out::println);
✅ 확장 예제 1: 스트림에서 예외 처리하기
🔹 상황
파일에서 숫자를 읽어 리스트로 만든 후, 각 숫자를 정수로 파싱하여 제곱값을 출력하려고 한다.
하지만 문자열이 숫자가 아닐 경우 예외가 발생할 수 있다.
List<String> inputs = Arrays.asList("10", "20", "a", "30");
inputs.stream()
.map(input -> {
try {
return Integer.parseInt(input);
} catch (NumberFormatException e) {
System.err.println("Invalid input: " + input);
return null;
}
})
.filter(Objects::nonNull)
.map(n -> n * n)
.forEach(System.out::println);
🔹 포인트
- 람다 내부에서 try-catch 사용 가능
- null 필터링을 통해 유효한 값만 처리
✅ 확장 예제 2: 병렬 스트림 (Parallel Stream)
🔹 상황
대규모 데이터 집합에 대해 연산을 빠르게 처리하고자 할 때, 멀티코어를 활용한 병렬 처리.
🔹 코드
List<Integer> numbers = IntStream.rangeClosed(1, 1000000)
.boxed()
.collect(Collectors.toList());
long start = System.currentTimeMillis();
int sum = numbers.parallelStream()
.filter(n -> n % 2 == 0)
.mapToInt(n -> n)
.sum();
long end = System.currentTimeMillis();
System.out.println("Sum of evens: " + sum);
System.out.println("Time taken: " + (end - start) + "ms");
🔹 포인트
- .parallelStream() 사용 시 멀티코어 자동 활용
- CPU-bound 작업일수록 효과 큼 (I/O 작업에는 부적절할 수 있음)
💡(알면좋고) CPU-bound란?
CPU-bound 작업이란, 프로그램이 CPU 연산 능력에 크게 의존하는 작업을 말한다.
즉, 컴퓨터의 계산 처리 속도가 작업의 병목(bottleneck)이 되는 경우이다.
| CPU-bound | CPU의 연산 능력이 제한 요인 | - 수학 계산- 해시 암호화- 영상 인코딩- 데이터 압축 |
| I/O-bound | 디스크, 네트워크 같은 입출력 속도가 병목 | - 파일 읽기/쓰기- DB 쿼리- API 요청- 사용자 입력 대기 |
✅ 확장 예제 3: 중첩 필터와 정렬, 매핑 조합
🔹 상황
고객 리스트에서 20세 이상이며 이름에 "김"이 포함된 사람만 추려 이름을 가나다 순으로 정렬 후 대문자로 출력
🔹 코드
class Customer {
String name;
int age;
public Customer(String name, int age) {
this.name = name; this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
List<Customer> customers = Arrays.asList(
new Customer("김철수", 25),
new Customer("홍길동", 30),
new Customer("이영희", 19),
new Customer("김민정", 22)
);
customers.stream()
.filter(c -> c.getAge() >= 20)
.filter(c -> c.getName().contains("김"))
.sorted(Comparator.comparing(Customer::getName))
.map(c -> c.getName().toUpperCase())
.forEach(System.out::println);
🔹 포인트
- filter 두 번 사용 가능 (조건 나눠서 처리 가능)
- Comparator.comparing()으로 정렬
- map으로 객체에서 이름 추출 후 대문자 변환
'Java' 카테고리의 다른 글
| @Postconstruct란? (0) | 2025.09.18 |
|---|---|
| Java - Enum 클래스 사용 (0) | 2023.10.05 |
| Java - 대용량 데이터 적재 로직 설계시 유념할 사항 (0) | 2022.11.04 |
| Java - properties 파일이란 무엇인가? (0) | 2022.06.17 |
| Java - String 자료형과 StringBuffer (0) | 2022.04.19 |