JAVA/Modern JAVA

[MODERN JAVA] 람다 깔끔하게 사용하기 ( 메서드 참조 )

IT록흐 2023. 6. 30. 19:09
반응형

 

람다는 메서드 참조로 깔끔하게 표현될 수 있다. 리스트를 정렬하는 코드를 람다로 표현하면 아래와 같다. 

 

람다표현식

List<String> str = Arrays.asList("a","b","A","B");
str.sort((s1,s2)-> s1.compareToIgnoreCase(s2));

 

List 인터페이스의 sort 메소드는 Comparator 함수형 인터페이스를 인수로 갖는다. 그럼 람다는 Compartor의 유일한 메서드인 compare()를 람다표현식으로 표현해야 한다. 

 

(s1,s2)-> s1.compareToIgnoreCase(s2) 

 

컴파일러는 함수형인터페이스의 함수디스크립터와 람다표현식이 호환되는지 검사한다. 

 

메서드 참조

List<String> str = Arrays.asList("a","b","A","B");
str.sort(String::compareToIgnoreCase);

 

람다표현식을 메서드 참조로 구현해보았다. 훨씬 직관적이고 가독성이 높다. 컴파일러는 함수형 인터페이스의 함수디스크립터와 람다Body에 사용된 메소드의 형식을 비교하여 호환 여부를 검사한다. 개발자가 사용할 메서드를 :: 로 표현하면 컴파일러가 자동으로 매핑하는 원리이다. 

 

 

메서드 참조 종류

 

1. 정적 메서드 참조(Static Method Reference): 클래스이름::정적메서드이름

// 정적 메서드
class MathUtils {
    public static int add(int a, int b) {
        return a + b;
    }
}

// 정적 메서드 참조
Function<Integer, Integer> addFunction = MathUtils::add;
int result = addFunction.apply(2, 3); // 결과: 5


2. 매개변수 메서드 참조(Instance Method Reference): 매개변수명::매개변수의메서드이름

// 클래스
class Printer {
    public void print(String message) {
        System.out.println(message);
    }
}

// 인스턴스 메서드 참조
Printer printer = new Printer();
//Consumer<String> printConsumer = ( printer, message ) -> printer.print(message);
Consumer<String> printConsumer = printer::print;
printConsumer.accept( printer, "Hello, world!"); // 출력: Hello, world!


3.  인스턴스 메서드 참조(Class::instanceMethod):인스턴스이름::인스턴스메서드이름

// 클래스
class Printer {
    public void print(String message) {
        System.out.println(message);
    }
}

// 인스턴스 메서드 참조
Printer printer = new Printer();
//Consumer<String> printConsumer = ( message ) -> printer.print(message);
Consumer<String> printConsumer = printer::print;
printConsumer.accept("Hello, world!"); // 출력: Hello, world!


4. 생성자 참조(Constructor Reference): 클래스이름::new

 

생성자 파라미터가 0개 혹은 1개 일때 

// 클래스
class Person {
    private String name;

    public Person(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

// 생성자 참조
Supplier<Person> personSupplier = Person::new;
Person person = personSupplier.get(); // 새로운 Person 인스턴스 생성
person.setName("John");
String name = person.getName(); // 결과: "John"

 

생성자 파라미터가 2개 일때 

// 클래스
class Point {
    private int x;
    private int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

// 생성자 참조
BiFunction<Integer, Integer, Point> pointCreator = Point::new;
Point point = pointCreator.apply(10, 20); // 새로운 Point 인스턴스 생성
int x = point.getX(); // 결과: 10
int y = point.getY(); // 결과: 20

 

반응형