티스토리 뷰
선수지식: [Java] - 람다식(Lambda Expression)
메서드 참조란?
메서드 참조(method reference)란 이미 존재하는 메서드 혹은 참조변수를 간결하게 지칭하는 방법이다. 람다식이 하나의 메서드만 호출하는 경우 그 식을 더 간결하게 나타내는 데에 쓰이며, 스트림 연산에서 빈번하게 사용된다. 이렇게 사용된 메서드 참조는 컴파일 단계에서 컴파일러가 알아서 람다식을 생성하여 처리된다.
사용법
람다식은 매개변수와 함수 몸체를 화살표(->)로 이어 구성했다면, 메서드 참조는 매개변수와 화살표, 소괄호를 제거하고 아래와 같이 쓴다.
클래스명(혹은 참조변수명)::메소드명
예시
1. Math.pow()
아래와 같이 Math.pow() 메서드의 람다식을 메서드 참조로 변형하여 사용 가능하다. pow()의 경우 두 개의 double형 매개변수를 받아 double형 결과를 내놓으므로, 기본 제공되는 함수형 인터페이스 중 ToDoubleBiFunction을 사용 가능하다.
ToDoubleBiFunction<Double, Double> function;
function = (a, b) -> Math.pow(a, b);
System.out.println(function.applyAsDouble(5.0, 2.0)); // 25
function = Math::pow;
System.out.println(function.applyAsDouble(5.0, 2.0)); // 25
2. System.out.print(), 스트림의 모든 요소 출력
같은 방법으로 System.out.print() 메서드도 메서드 참조로 변형 가능하다. 매개변수를 받고 리턴값이 없는 기본 제공 함수형 인터페이스 Consumer<T>를 사용 가능하다.
Consumer<String> consumer;
consumer = (a) -> System.out.print(a);
consumer.accept("print"); // print
consumer = System.out::print;
consumer.accept("print\n"); // print
물론 위와 같이 직접 함수형 인터페이스의 구현체를 만드는 대신, 아래와 같이 메서드 참조는 스트림을 통해 많이 사용된다.
List<Integer> intList = List.of(1,2,3);
Stream<Integer> intStream = intList.stream();
intStream.forEach(System.out::print); // 123
Stream.class의 최종 연산인 forEach()를 살펴보면 Consumer를 입력으로 받기 때문임을 알 수 있다.
3. 생성자 참조
생성자의 호출도 람다식으로 표현할 수 있으므로, 이것을 다시 메서드 참조를 사용해 간결하게 만들 수 있다.
// 위 아래가 같은 의미
() -> new Object
Object::new // 클래스명::new
4. Stream에 메서드 참조 사용하기
간단히 점수 class를 생성하고 리스트에 객체들을 담아 100점을 초과하는 점수 객체를 찾는다. 해당 객체를 찾지 못하면 IllegalArgumentException을 발생시킨다. 아래와 같이 Stream에 람다식만을 사용하여 적을 수 있다.
void test() {
List<Score> scores = new ArrayList<>();
scores.add(new Score(100));
scores.add(new Score(120));
Score score = scores.stream()
.filter(s -> s.over100())
.findFirst()
.orElseThrow(() -> new IllegalArgumentException());
}
class Score {
int score;
public Score(int score) {
this.score = score;
}
public boolean over100() {
return this.score>100;
}
}
위의 Stream에 사용된 두 람다식이 파라미터 없이 하나의 메서드만 호출하므로 아래와 같이 메서드 참조를 사용하도록 변경 가능하다. (클래스 명::메서드 명)의 형태로 메서드인 over100과 Exception의 생성자를 참조한다.
void test() {
List<Score> scores = new ArrayList<>();
scores.add(new Score(100));
scores.add(new Score(120));
Score score = scores.stream()
.filter(Score::over100)
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
'Java' 카테고리의 다른 글
[Java] 템플릿 콜백 패턴으로 동일한 작업을 효율적으로 처리하기 (1) | 2023.03.04 |
---|---|
[Java] 원시값을 포장해 사용하자 (2) | 2023.02.26 |
[Java] Comparator 구현부터 디폴트 메서드까지 활용해 정렬하기 (0) | 2022.09.15 |
[Java] 람다식(Lambda Expression) (0) | 2022.09.14 |
[Java] 왜 '함수형' 인터페이스는 특별할까? (0) | 2022.09.07 |
- Total
- Today
- Yesterday
- GitHub Discussion
- Spring Boot Monitoring
- 우테코 5기
- logback-spring.xml
- stubbing
- MySQL
- JPA JSON
- Spring 테스트
- Payload 암호화
- 스프링
- 함수형 인터페이스
- Fromtail
- 우테코 프리코스
- Jenkins 예약 배포
- invokedynamic
- java switch case
- springboottest
- 자바
- GitHub Discussion Template
- thenComparing
- JPA
- Java
- RandomPort
- 생성자 주입
- MySQL 이벤트 스케줄
- Spring
- 우테코
- 람다식
- 의존성 주입
- GitHub Discussion 템플릿
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |