본문 바로가기
java

Lambda 01

by 킹차니 2021. 12. 23.

 

 

함수형 언어는 jdk 1.8부터 시작.

람다식 : 함수(메서드)를 간단한 식으로 표현하는 방법

int max(int a, int b){
	return a > b ? a : b;
}

 

위와 같은 메소드를 아래처럼 간단한 식으로 만들어준다.

(a, b) -> a > b ? a: b

 

람다식은 익명함수이다.

 

람다식을 작성하는 방법

1. 메서드의 이름과 반환타입을 제거하고 →을 { }블록 앞에 추가한다. 

(int a, int b) -> {return a > b ? a : b}

 

2. 반환값이 있는 경우, 식이나 값만 적고 Return문 생략가능(끝에 ';' 안붙임)

(int a, int b) -> a > b ? a : b

 

3. 매개변수의 타입이 추론가능하면 생략가능

(a, b) -> a > b ? a: b

 

 

람다식 작성 주의점

1. 매개변수가 하나인 경우, 괄호 생략가능(타입이 없을 때만)

a -> a * a //OK
int a -> a * a //ERROR

 

2. 블록 안의 문장이 하나일 때만, 괄호 생략이 가능하다.(끝에 ';' 안붙임)

(int i) ->{
	System.out.println(i);
}

//아래와 같이 괄호 생략 가능. 세미콜론은 없어야한다.
(int i) -> System.out.println(i)

 

EX ) 문제를 람다식으로 표현하기

// 문제 1
int max(int a, int b){
	return a > b ? a : b;
}
//정답
(a, b) -> a > b ? a : b

// ---------------------------------------------

//문제 2
int printVar(String name, int i){
	System.out.println(name+"="+i);
}
//정답
(name, i) -> System.out.println(name+"="+i)

// ---------------------------------------------

// 문제 3
int square(int x){
	return x * x;
}
//정답
x -> x * x

// ---------------------------------------------

// 문제 4
int roll(){
	return (int)(Math.random()*6);
}
//정답
() -> (int)(Math.random()*6)

 

 

람다식은 익명함수가 아닌 익명 객체이다.

 

(a, b) -> a > b ? a : b

//위 람다식은 아래와 같다. (익명 클래스: 객체의 선언과 생성을 동시에 한다.)
new Object(){
	int max(int a, int b){
		return a > b ? a : b;
	}
}

 

 

함수형 인터페이스

함수형 인터페이스 : 단 하나의 추상 메서드만 선언된 인터페이스

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

 

함수형 인터페이스 MyFunction을 익명 클래스로 생성하기 :

MyFuction f = new MyFunction(){
	public int max(int a, int b){
		retuen a > b ? a : b;
  }
};

 

위에서 보이다시피 함수형 인터페이스를 익명클래스로 생성할 수 있다.

즉 위의 MyFunction타입인 f의 메소드에 접근할 수 있다.(조상인 MyFunction 함수형 인터페이스에 메소드가 정의되어 있으므로)

int value = f.max(3, 5); //OK. MyFunction에 max()가 있음

 

함수형 인터페이스 타입의 참조변수로 람다식을 참조할 수 있다.

MyFunction f = (a, b) -> a > b ? a : b;
int value = f.max(3, 5); // 실제로는 람다식(익명 함수)이 호출됨

이처럼 함수형 인터페이스는 람다식을 참조로 사용하기 위해서 사용된다.

즉, 익명 객체인 람다식을 일반적인 객체의 메소드를 사용하는 것처럼 사용할 수 있게 해준다.

public class LambdaPractice {
    public static void main(String[] args) {
//        Object obj = (a, b) -> a > b ? a : b; //람다식. 익명 객체

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

        /*람다식을 다루기 위한 참조변수의 타입은 함수형 인터페이스로 한다.*/
        MyFunction f = (a, b) -> a > b ? a : b;

        int value = f.max(3, 5); /*함수형 인터페이스*/
        System.out.println("value = "+value);

    }
}

@FunctionalInterface//단 하나의 추상 메서드만 가져야 한다.
interface MyFunction{
    public abstract int max(int a, int b);
}

위의 코드를 보면 Object타입으로 참조하여 람다식을 사용하려 했을 때는 Object에 max라는 메소드가 정의되어 있지 않기 때문에 사용할 수 없었지만, 함수형 인터페이스 MyFunction에 max를 정의하면 MyFunction타입으로 참조하여 사용할 수 있다.

 

 

Collection.sort :

Collections.sort에 익명 객체 대신 람다식을 사용할 수 있다.

public class Ex1401 {
    public static void main(String[] args) {

        List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "ada");
        Collections.sort(list, new Comparator<String>(){//익명 객체
            @Override
            public int compare(String s1, String s2) {
                return s2.compareTo(s1);
            }
        });

        /* 익명 객체를 람다식으로 대체 */

        List<String> list2 = Arrays.asList("abc", "aaa", "bbb", "ddd", "ada");
        Collections.sort(list2, (s1, s2)->s2.compareTo(s1));//람다식

        for (String s : list) System.out.print(s + " ");
        System.out.println();
        for (String s : list) System.out.print(s + " ");
    }
}

실행결과:
ddd bbb ada abc aaa
ddd bbb ada abc aaa

 

함수형 인터페이스를 매개변수로 할 수도 있다.

@FunctionalInterface
interface MyFunction{
	void myMethod();
}

public void aMethod (MyFunction f){
	f.myMethod(); // MyFunction에 정의된 myMethod 메소드 호출
}
MyFunction f = () -> System.out.println("myMethod()");
aMethod(f);
aMethod(()-> System.out.println("myMethod()"));

 

함수형 인터페이스를 반환할 수도 있다.

MyFunction myMethod(){
	Myfunction f = () -> {};
	return f;
}

//위 코드와 아래 코드 모두 같다.

MyFunction myMethod(){
	return () -> {};
}

 

 

 

출처: 남궁성님 유튜브 강의
https://www.youtube.com/user/MasterNKS

'java' 카테고리의 다른 글

Lambda 03 Predicate의 결합  (0) 2021.12.26
Lambda 02 - java.util.function 패키지  (0) 2021.12.23
Serializable  (0) 2021.11.21
인터페이스 - 느슨한 결합력  (0) 2021.04.25
자바의 다형성  (0) 2021.03.25