자바썸
자바랑 썸타는중
자바썸

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
자바썸

자바랑 썸타는중

Language/Java

[Java] 람다식

2022. 6. 6. 19:25

람다식이란? 

 

메서드를 하나의 식으로 표현한 것이다. 람다식은 함수를 간략하고 명확하게 표현하게 해준다.

람다식으로 표현하면 메서드의 이름과 반환값이 없어지므로, '익명 함수'라고도 한다.

 

람다식 작성하기

 // 두 값 중에서 큰 값을 반환하는 메서드
 int max(int a, int b){
     return a > b ? a : b;
 }
 
 // 아래와 같이 표현할 수 있다.
 (int a, int b){
     return a > b ? a : b;
}

 반환값이 있는 메서드의 경우, return문 대신 식으로 대신 할 수 있다. 식의 연산 결과가 자동적으로 반환값이 된다. 

이때는 문장이 아닌 식이므로 끝에 ';'을 붙이지 않는다.
(int a, int b) -> {return a > b ? a : b;} -----> (int a, int b) -> a > b ? a : b

선언된 매개변수의 타입은 추론이 가능한 경우 생략 가능하다.
(int a, int b) -> a > b ? a : b -----> (a, b) -> a > b ? a : b

선언된 매개변수가 하나일 경우 괄호를 생략할 수 있다. 단, 매개변수의 타입이 있으면 괄호를 생략할 수 없다.
(a) -> a * a			a -> a * a // OK
(int a) -> a * a  ------> 	int a - > a * a //에러

괄호 안의 문장이 하나일 때는 괄호를 생략할 수 있다. 이때 문장의 끝에 ';'를 생략해야 한다.
(String name, int i ) -> {			(String name, int i) ->
 System.out.println(name + "=" + i);  ----->		System.out.println(name + "=" + i)
}

그러나 괄호 안의 문장이 return문일 경우 괄호를 생략할 수 없다.
(int a, int b) -> { return a > b ? a : b;} //OK
(int a, int b) ->  return a > b ? a : b    //에러

 

함수형 인터페이스 

max()라는 메서드가 정의된 MyFunction인터페이스가 정의되어 있다고 가정하자.

public interface MyFunction {

    public abstract int max(int a, int b);
}


MyFunction f = new MyFunction() { // 익명 객체
    public int max(int a, int b) {
        return a > b ? a : b;
    }
};

int big = f.max(5,3); // 익명 객체의 메서드를 호출

위 코드의 익명 객체를 함다식으로 아래와 같이 대체할 수 있다.

MyFunction f = (int a, int b) -> a > b ? a : b;// 익명 객체를 람다식으로 대체
int big = f.max(5,3); // 익명 객체의 메서드를 호출

하나의 메서드가 선언된 인터페이스를 정의해서 람다식을 다루는 것은 기존의 자바의 규칙들을 어기지 않으면서도 자연스럽다. 그래서 인터페이스를 통해 람다식을 다루기로 결정되었으며, 람다식을 다루기 위한 인터페이스를 '함수형 인터페이스'라고 부른다.

@FunctionalInterface
public interface MyFunction {
    public abstract int max(int a, int b);
}

주의할 점은 오직 하나의 추상 메서드만 정의되어 있어야 한다는 것이다. 그래야 람다식과 인터페이스의 메서드가 1:1로 연결될 수 있기 때문이다. 

 

Java.util.function 패키지

일반적으로 자주 쓰이는 형식의 메소드를 함수형 인터페이스로 미리 정의해놓았다. 매번 새로운 함수형 인터페이스를 정의하지 말고, 가능하면 이 패키지의 인터페이스를 활용하는 것이 좋다. ('T'는 Type, 'R'은 Return Type을 의미한다.)

함수형 인터페이스  메서드 설명
java.lang.Runnable run() 매개변수 X, 반환값 X
Supplier<T> get() 매개변수 X, 반환값 O
Consumer<T> accept(T t) 매개변수 O, 반환값 X
Function<T,R> apply(T t) 하나의 매개변수를 받아 결과 반환
Predicate<T> test(T t) 조건식을 표현하는데 사용
매개변수는 하나, 반환 타입은 boolean

 

매개변수가 두 개인 함수형 인터페이스

 

함수형 인터페이스 메서드 설명
BiConsumer<T,U> accept<T t, U u> 두 개의 매개변수만 있고 반환값 없음
BiPredicate<T,U> test<T t, U u> 조건식 표현에 사용, 
매개변수 둘, 반환값은 boolean
BiFunction<T,U,R> apply(T t, U u) 두 개의 매개변수를 받아 하나의 결과로 반환

 

기본형을 사용하는  함수형 인터페이스

 

보다 효율적으로 처리할 수 있도록 기본형을 사용하는 함수형 인터페이스들이 제공된다.

함수형 인터페이스 메서드 설명
DoubleToIntFunction applyAsInt(double d) AToBFunction은 입력이 A타입
출력이 B타입
ToIntFunction<T> applyAsInt(T value) ToBFunction은 출력이 B이다.
입력은 제네릭 타입
intFunction<R> apply(T t, U u) AFunction은 입력이 A,
출력은 제네릭 타입
ObjectConsumer<T> accept(T t, U u) ObjAFunction은 입력이 T, A 타입
출력은 없다.

 

메서드 참조

'메서드 참조'라는 방법으로 람다식을 간략히 할 수 있다.

                    Function<String, Integer> f= (String s) -> Integer.parseInt(s);
                                        	  ↓
                    Function<String, Integer> f= Integer::parseInt;

위 메서드 참조에서 람다식의 일부가 생략되었지만, 컴파일러는 생략된 부분을 우변의 parseInt메서드의 선언부로부터, 또는 좌변의 Function인터페이스에 지정된 제네릭 타입으로부터 쉽게 알아낼 수 있다.

종류 람다 메서드 참조
static 메서드 참조 (x) -> ClassName.method(x) ClassName::method
인스턴스메서드 참조 (obj,x) -> obj.method(x) ClassName::method
특정 객체 인스턴스메서드 참조 (x) -> obj.method(x) obj::method

하나의 메서드만 호출하는 람다식은 '클래스이름::메서드이름' 또는 '참조변수::메서드이름'으로 바꿀 수 있다.

 

생성자의 메서드 참조 

Supplier<MyClass> s = () -> new MyClass(); // 람다식
Supplier<MyClass> s = MyClass::new; 	   // 메서드 참조

매개변수가 있는 생성자라면, 매개변수의 개수에 따라 알맞은 함수형 인터페이스를 사용하면 된다.
Function<Integer,MyClass> f = (i) -> new MyClass(i); // 람다식
Function<Integer,MyClass> f = MyClass::new;	     // 메서드 참조

배열을 생성할 때는 아래와 같이 한다.
Function<Integer,int[]> f = x -> new int[x]; // 람다식
Function<Integer,int[]> f = int[]::new;	     // 메서드 참조

 

'Language > Java' 카테고리의 다른 글

[Java]스트림(stream)(2/3)  (0) 2022.06.07
[Java]스트림(stream)(1/3)  (0) 2022.06.07
예외처리(Exception Handling)  (0) 2022.05.27
객체 지향 프로그래밍에 대해 묻는다면 ?  (0) 2022.05.25
Java는 어떻게 동작하지?( + 메모리 영역)  (0) 2022.05.23
    'Language/Java' 카테고리의 다른 글
    • [Java]스트림(stream)(2/3)
    • [Java]스트림(stream)(1/3)
    • 예외처리(Exception Handling)
    • 객체 지향 프로그래밍에 대해 묻는다면 ?
    자바썸
    자바썸

    티스토리툴바