람다 표현식

JUNG GYUWON·2023년 10월 14일
0

Java

목록 보기
16/18

람다표현식

메소드를 하나의 식으로 표현한 것입니다.

메소드

int min(int x, int y) {
    return x < y ? x : y;
}

람다표현식

(x, y) -> x < y ? x : y;

그러면 이걸 왜 쓰는가?

  • 클래스를 작성하고 객체를 생성하지 않아도 메소드를 사용할 수 있다
  • 불필요한 코드를 줄이고 가독성을 높일 수 있다

람다 표현식 작성
자바에서는 (매개변수목록) -> { 함수몸체 }와 같이 람다 표현식을 작성한다

자바에서 람다 표현식을 작성할 때 유의해야 할 사항은 다음과 같다

  1. 매개변수의 타입을 추론할 수 있는 경우에는 타입을 생략할 수 있다.
// 타입을 명시한 경우
(String s) -> System.out.println(s)
// 타입을 생략한 경우
s -> System.out.println(s)
  1. 매개변수가 하나인 경우에는 괄호(())를 생략할 수 있다.
// 괄호를 사용한 경우
(s) -> System.out.println(s)

// 괄호를 생략한 경우
s -> System.out.println(s)
  1. 함수의 몸체가 하나의 명령문만으로 이루어진 경우에는 중괄호({})를 생략할 수 있다. (이때 세미콜론(;)은 붙이지 않음)
// 중괄호를 사용한 경우
s -> { System.out.println(s); }

// 중괄호를 생략한 경우
s -> System.out.println(s)
  1. 함수의 몸체가 하나의 return 문으로만 이루어진 경우에는 중괄호({})를 생략할 수 없다
// 잘못된 예
x -> return x * x;  

// 올바른 예
x -> x * x
  1. return 문 대신 표현식을 사용할 수 있으며, 이때 반환값은 표현식의 결괏값이 된다
    (이때 세미콜론(;)은 붙이지 않음)
// return 문을 사용한 경우
x -> { return x * x; }

// 표현식을 사용한 경우 (return 및 세미콜론 생략)
x -> x * x

함수형 인터페이스(functional interface)

Java 8부터 도입된 개념으로, 오직 하나의 추상 메서드만을 포함하는 인터페이스를 의미

왜 쓰는가?

람다표현식을 통해서 해당 함수를 작성하는 것으로 코드의 부족한 부분을 사용자가 지정해서 줄 수 있음

@FunctionalInterface // 위와 같은 어노테이션을 사용하여 함수형 인터페이스임을 명시
public interface MyFunctionalInterface {
    void execute();
}

public class Lambda02 {
  public static void main(String[] args) {
      runTask(() -> System.out.println("Task 1"));
      runTask(() -> System.out.println("Task 2"));
  }

  public static void runTask(MyFunctionalInterface task) {
      task.execute();
}

}
Task 1
Task 2

stream에서 map 이나 filter를 사용했던 것도 그 뒷단은 함수형 인터페이스 임

List<String> list = Arrays.asList("A", "B", "C");
list.stream().filter(s -> s.startsWith("A")).forEach(System.out::println); // "A"
List<String> list = Arrays.asList("A", "B", "C");
list.stream().map(s -> s.toLowerCase()).forEach(System.out::println); // "a" "b" "c"

이렇게 함수형 인터페이스를 통해 람다식으로 함수를 정의하고 exectue()를 실행한거라고 보면 됨


메소드 참조

람다 표현식이 단 하나의 메소드만을 호출하는 경우에 해당 람다 표현식에서 불필요한 매개변수를 제거하고 사용할 수 있도록 해준다

문법:
클리스이름::메소드이름
참조변수이름::메소드이름

람다표현식

(base, exponent) -> Math.pow(base, exponent);

위의 예제는 단순히 Math 클래스의 pow() 메소드로 인수를 전달하는 역할만 하므로, 메소드 참조를 사용하여 아래와 같이 표현할 수 있다

Math::pow;

특정 인스턴스의 메소드를 참조할 때에도 참조 변수의 이름을 통해 메소드 참조를 사용할 수 있다

MyClass obj = new MyClass;

Function<String, Boolean> func = (a) -> obj.equals(a); // 람다 표현식
Function<String, Boolean> func = obj::equals(a);       // 메소드 참조
DoubleUnaryOperator oper;

oper = (n) -> Math.abs(n); // 람다 표현식
System.out.println(oper.applyAsDouble(-5));

oper = Math::abs; // 메소드 참조
System.out.println(oper.applyAsDouble(-5));
5.0
5.0

DoubleUnaryOperator 인터페이스는 한 개의 double 형 매개변수를 전달받아 한 개의 double 형 값을 반환하는 java.util.function 패키지에서 제공하는 함수형 인터페이스이다

profile
반가워요😎

0개의 댓글