![[Java] 람다식을 더 짧게 - 메서드 참조 Method Reference](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4HGND%2FbtspFMxj6SV%2F5RcHV51OcmLGEjOUOT4dm0%2Fimg.png)

Method Reference
- Java 8 도입
- 하나의 메서드만 호출하는 람다식은 메서드 참조로 간소화하여 표현가능하다 (전달 인자를 생략하여 코드 간결해짐)
- 구분자로 :: 사용
- 아래의 4가지 유형 있음
아래 코드는 정렬할 때 [클래스 구현 -> 람다 -> 람다 간소화 -> 정적 메서드 참조]에 대한 비교 예시이다
// 배열 선언
Person[] perons = ...
// (1) Comparator 구현 방식 (구 시대적)
class PersonAgeComparator implements Comparator<Person> {
public int compare(Person a, Person b) {
return a.age().compareTo(b.age());
}
}
Arrays.sort(persons, new PersonAgeComparator()); // 나이순 오름차순 정렬
// (2) 람다 표현식을 사용하는 경우
Arrays.sort(persons, (Person a, Person b) -> {
return a.age().compareTo(b.age();
});
// (3) 람다 표현식 간소화
Arrays.sort(persons, (a, b) -> Person.compare(a, b)); // Person 클래스 Comparable 구현했을 때
// (4) 정적 메서드 참조를 할 경우, 전달 인자 생략
Arrays.sort(persons, Person::compare);
1. Reference to a static method (정적 메서드 참조)
className::staticMethodName 형식으로 표기
임의 클래스가 있을 때
public class MethodReferenceTest {
public static <T> T mergeThing(T a, T b, BiFunction<T, T, T> merger) {
return merger.apply(a, b);
}
public static String appendStrings(String a, String b) {
return a + b;
}
public String appendString(String a, String b) {
return a + b;
}
}
예시
String t1 = "Hello";
String t2 = "World!";
String result = "HelloWorld!";
// Calling the method mergeThings with a lambda expression (람다 표현식 사용)
String lambdaResult = MethodReferenceTest.mergeThing(t1, t2, (a, b) -> a + b);
assertThat(lambdaResult).isEqualTo(result); // Ok
// *Reference to a static method (클래스 정적 메서드 참조)
String staticMethodResult = MethodReferenceTest.mergeThing(t1, t2, MethodReferenceTest::appendStrings);
assertThat(staticMethodResult).isEqualTo(result); // Ok
2. Reference to an instance method of a particular object (인스턴스 메서드 참조)
objectName::instanceMethodName 형식으로 표기
- new 키워드로 인스턴스 선언한 객체의 메서드 참조한다
- public String appendString() {..} 인스턴스 메서드 사용
예시
String t1 = "Hello";
String t2 = "World!";
String result = "HelloWorld!";
// Reference to an instance method of a particular object
MethodReferenceTest obj = new MethodReferenceTest();
String instanceMethodResult = MethodReferenceTest.mergeThing(t1, t2, obj::appendString);
assertThat(instanceMethodResult).isEqualTo(result); // Ok
3. Reference to an instance method of an arbitrary object of a particular type
ClassName::instanceMethodName 형식으로 표기
- 인스턴스 참조 유형으로 String, Integer, List 등에서 제공되는 클래스의 인스턴스 메서드 참조
예시
String t1 = "Hello";
String t2 = "World!";
String result = "HelloWorld!";
String particularTypeResult = MethodReferenceTest.mergeThing(t1, t2, String::concat); // t1.concat(t2)
assertThat(particularTypeResult).isEqualTo(result); // Ok
Integer::compareTo (오름차순 정렬)
//Integet.class
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
@Test
void instanceMethodReference() {
List<Integer> numbers = Arrays.asList(5, 3, 50, 24, 40, 2, 9, 18);
List<Integer> sorted = numbers.stream().sorted(Integer::compareTo).collect(Collectors.toList());
assertThat(sorted).containsExactly(2, 3, 5, 9, 18, 24, 40, 50);
}
String::compareToIgnoreCase (오름차순 정렬)
// String.class
public int compareToIgnoreCase(String str) {
return CASE_INSENSITIVE_ORDER.compare(this, str);
}
@Test
void instanceMethodOfAnArbitraryObjectOfParticularType() {
String[] strings = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(strings, String::compareToIgnoreCase);
assertThat(strings)
.containsExactly("Barbara", "James", "John", "Linda", "Mary", "Michael", "Patricia", "Robert");
}
4. Reference to a constructor (생성자 참조)
className::new 형식으로 표기
- 당연히 생성자의 파라미터 개수 맞춰줘야 함
예시
class Bicycle {
String brand;
public Bicycle(String brand) { this.brand = brand; }
}
@DisplayName("")
@Test
void constructReferenceMethod2() {
List<String> bikeBrand = Arrays.asList("Giant", "Scott", "Trek", "GT");
Bicycle[] bicycles = bikeBrand.stream().map(Bicycle::new).toArray(Bicycle[]::new);
assertThat(bicycles).hasSize(4);
}
아래와 같은 추상 클래스 구현한 상속관계의 클래스가 있을 때
public abstract class Car {
protected String name;
protected String brand;
public Car(String name, String brand) {
this.name = name;
this.brand = brand;
}
public abstract void drive();
}
public class Sedan extends Car{
public Sedan(String name, String brand) {
super(name, brand);
}
@Override
public void drive() {
System.out.println(String.format("Driving a sedan %s name %s", name, brand));
}
}
public class Suv extends Car{
public Suv(String name, String brand) {
super(name, brand);
}
@Override
public void drive() {
System.out.println(String.format("Driving a Suv %s name %s", name, brand));
}
}
public class Van extends Car {
public Van(String name, String brand) {
super(name, brand);
}
@Override
public void drive() {
System.out.println(String.format("Driving a Van %s name %s", name, brand));
}
}
Map에 각 키 마다 참조를 넣어두고 사용할 수 도 있다. (패스트 캠퍼스 참고.)
@Test
void constructorMethodReferenceMap() {
// {키, name, brand}
String[][] inputs = new String[][] {
{"sedan", "Sonata", "Hyundai"},
{"van", "Sienna", "Toyota"},
{"sedan", "Model S", "Tesla"},
{"suv", "Sorento", "KIA"}
};
// BiFunction -> String, String 인자를 받아 Car 타입을 리턴
Map<String, BiFunction<String, String, Car>> constructorMap = new HashMap<>();
constructorMap.put("sedan", Sedan::new);
constructorMap.put("van", Van::new);
constructorMap.put("suv", Suv::new);
List<Car> cars = new ArrayList<>();
for(String[] input : inputs) {
cars.add(constructorMap.get(input[0]).apply(input[1], input[2]));
}
assertThat(cars).hasSize(4); // Ok
}
참고
https://fastcampus.co.kr/dev_red_lsh
The Red: 25개 백엔드 개발 필수 현업 예제를 통해 마스터하는 JAVA STREAM | 패스트캠퍼스
글로벌 SNS 기업이자 자바 오픈 소스 분야의 강자인 LinkedIn의 시니어 소프트웨어 엔지니어인 이승환 강사의 강의입니다. 이승환 강사는 백엔드 개발자로 LinkedIn에서 회원관리 및 거래 관리 부분
fastcampus.co.kr
https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
Method References (The Java™ Tutorials > Learning the Java Language > Classes and Objects)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated
docs.oracle.com
'공부 > Java' 카테고리의 다른 글
[Java] Stream 생성 (파일 데이터 제외) (0) | 2023.08.03 |
---|---|
[Java] Stream API (0) | 2023.08.03 |
[Java] Optional 클래스 메서드 (자바의 정석) (0) | 2023.08.01 |
[Java] Iterators 인터페이스 (자바의 정석) (0) | 2023.07.31 |
[Java] Arrays 클래스 메서드 (자바의 정석) (0) | 2023.07.31 |

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!