반응형
메서드 참조란?
메서드 참조는 특정 람다의 축약형이라고 생각할 수 있다.
메서드 참조를 이용하면 기존 메서드 정의를 재활용해서 람다처럼 전달할 수 있으며 때로는 람다 표현식보다 메서드 참조를 사용하는 것이 더 가독성이 좋으며 자연스러울 수 있다.
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())); // 람다 표현식
inventory.sort(compareTo(Apple::getWeight)); // 메서드 참조
위 코드를 보면 Apple::getWeight는 Apple에 정의된 getWeight의 메서드 참조다. 메서드명 앞에 구분자(::)를 분해 방식으로 메서드 참조를 활용하였다.
메서드 참조를 이용하면 같은 기능을 더 간결하게 구현할 수 있어서 가독성을 높일 수 있다.
메서드 참조를 새로운 기능이 아니라 하나의 메서드를 참조하는 람다를 편리하게 표현할 수 있는 문법으로 간주하면 되겠다.
메서드 참조를 만드는 방법
메서드 참조는 세 가지 유형으로 구분할 수 있다.
1. 정적 메서드 참조
// 람다 표현식
ToIntFunction<String> stringToInt = (String s) -> Integer.parseInt(s);
// 메서드 참조
Function<String, Integer> stringToInteger = Integer::parseInt;
2. 다양한 형식의 인스턴스 메서드 참조
// 람다 표현식
BigPredicate<List<String>, String> contains = (list, element) -> list.contains(element);
// 메서드 참조
BigPredicate<List<String>, String> contains = List::contains;
3. 기존 객체의 인스턴스 메서드 참조
// 람다 표현식
Predicate<String> startsWithNumber = (String s) -> this.startsWithNumber(s);
// 메서드 참조
Predicate<String> startsWithNumber = this::startsWithNumber;
이 유형은 비공개 헬퍼 메서드를 정의한 상황에서 유용하게 활용할 수 있다.
생성자 참조란?
ClassName::new 처럼 클래스명과 new 키워드를 이용해서 기존 생성자의 참조를 만들 수 있다. 이것은 정적 메서드의 참조를 만드는 방법과 비슷하다. 아래는 여래 색상의 자동차를 만드는 예제 코드이다.
@ToString
@AllArgsConstructor
public class Car {
private String color;
}
public List<Car> map(List<String> list, Function<String, Car> f) {
List<Car> results = new ArrayList<>();
for(String s:list) {
results.add(f.apply(s));
}
return results;
}
List<String> colors = Arrays.asList("Gray", "Black", "White");
List<Car> cars = map(colors, Car::new); // map 메서드로 생성자 참조 전달
// [Car{color='Gray'}, Car{color='Black'}, Car{color='White'}]
만약 인수가 두 개라면 BiFunction을 사용하면 되고 세 개라면 TriFunction을 사용하면 된다.
@ToString
@AllArgsConstructor
public class Car {
private String color;
private Integer price;
}
public List<Car> map(Map<String, Integer> map, BiFunction<String, Integer, Car> f) {
List<Car> results = new ArrayList<>();
for (String color : map.keySet()) {
results.add(f.apply(color, map.get(color)));
}
return results;
}
Map<String, Integer> carInfos = new HashMap<>() {{
put("Gray", 30000000);
put("White", 31000000);
put("Black", 32000000);
}};
List<Car> cars = map(carInfos, Car::new); // map 메서드로 생성자 참조 전달
// [Car{color='Gray', price='30000000'}, Car{color='White', price='31000000'}, Car{color='Black', price='32000000'}]
정리해보자면,
동작 파라미터화를 람다 표현식을 사용해 가독성 좋게 구현하고, 이 람다 표현식을 메소드 참조와 생성자 참조를 사용하여 조금 더 가독성 좋게 코드를 구현할 수 있다.
반응형
'Java' 카테고리의 다른 글
[모던 자바] 스트림(Stream)이란 무엇인가? (0) | 2022.03.02 |
---|---|
[모던 자바] 람다 표현식을 조합할 수 있는 유용한 메서드 (0) | 2022.03.02 |
[모던 자바] Java 8 API에서 지원하는 함수형 인터페이스 (0) | 2022.02.28 |
[모던 자바] 람다란 무엇인가? (0) | 2022.02.28 |
[모던 자바] 동작 파라미터화란 무엇인가? (2) | 2022.02.27 |