[JAVA] 람다식과 함수형

1. 람다 식

(1) 정의

익명 함수(이름이 없는 함수) == 액세스 한정자, 반환 유형, 함수 이름 및 매개변수 데이터 유형은 모두 불필요합니다.

람다 식도 일급 객체입니다.

**프라임 속성이란 무엇입니까?

데이터나 변수를 받을 수 있는 객체, 특정 메서드의 매개변수로 입력할 수 있는 객체, 특정 메서드의 반환값이 될 수 있는 객체입니다.

(2) 모양

(패스 값 1, 패스 값 2, …) -> { 코드 }

2. 기능적 인터페이스

(1) 의미

하나의 추상 메서드만 있는 인터페이스

(2) 람다 식과의 관계

람다 식은 기능적 인터페이스를 통해서만 액세스할 수 있습니다.

**왜?

인터페이스에 두 개의 추상 메서드가 있는 경우 어떤 추상 메서드가 람다 식과 일치하는지 모호해집니다.

따라서 하나의 추상 메서드만 있는 기능적 인터페이스만 람다 식과 일치시켜 사용할 수 있습니다.

(둘 사이의 매개변수 개수와 반환값 유무가 일치해야 합니다.
)


3. 코드 리뷰

(1) 인수가 하나이고 반환형이 void인 추상 메서드의 경우

// <<인터페이스 부분>>
//함수형 인터페이스에 추상 매소드가 1 개여야만 한다고 컴퓨터에게 가르쳐 주기 위해 어노테이션 이용
// 해당 어노테이션 있으면, 추상 매소드가 2개가 될 때, 컴퓨터가 에러를 말해준다.
@FunctionalInterface public interface Convertible { // USD를 환전하는 추상 매소드 void convert(int USD); }
 
 /* 함수형 인터페이스 객체와 그 객체의 매소드에 넣을 값으로 이루어진 함수
 
 	인터페이스는 일반적으로 객체를 가질 수 없지만, 람다식으로 추상매소드를 바로 구체화 시키기 때문에
    람다식으로 매칭한 경우에는 가능 */
    
 public static void convertUSD(Convertible converter, int USD){
        converter.convert(USD);
    }
}
// 람다식을 통해 인터페이스에서 바로 객체를 생성했고, 
//(다형성의 원리: 부모 클래스의 참조 변수는 자식 클래스의 객체를 참조할 수 있다.
) Convertible convertible = (USD) -> System.out.println(USD + "달러 = "+ (USD *1400) + " 원"); // 만들어진 객체와 해당 객체 매소드에 넣을 값을 파라미터로 보냈다.
// 람다식이 곧 추상 매소드의 구체화 이므로 해당 2는 USD로 보내진다.
convertUSD(convertible,2);
// * 객체 생성 과정 없이 람다식 자체를 파라미터로 보낼 수도 있다.
// * 어짜피 파라미터인 Convertible converter와 만나 객체가 생성되므로 밑과 같은 표기도 가능하다.
convertUSD((USD) -> System.out.println(USD + "달러 = "+ (USD *1400) + " 원"), 1);

(2) 추상 메서드에 인수가 없고 반환 유형이 유효하지 않은 경우

// 함수형 인터페이스

@FunctionalInterface
public interface ConvertibleWithNoParams {
    void convert();
}
ConvertibleWithNoParams c1 = () -> System.out.println("1달러는 1400원");

// 추상 매소드 호출하면 위의 람다식이 해당 호출에 응하여 일을 수행한다.
c1.convert();

(3) 람다 식의 코드 부분이 한 줄인지 두 줄 이상인지 구분

** 람다 식의 코드 부분이 두 줄 이상인 경우 () -> {}; 까지 {}; 부분을 ​​작성해야 합니다.
(한 줄이면 생략 가능)

// 위의 함수형 인터페이스 계속 사용 
c1 = () -> {
    int USD = 5;
    int KRW = 1400;
    System.out.println(USD + "달러 = "+ (USD *KRW) + " 원");
};

(3) 추상 메서드에 두 개 이상의 인수가 있는 경우 반환 형식은 무효입니다.

** 둘 사이의 인수 수를 일치시킬 수 있습니다.

public interface ConvertibleWithTwoParams {
    void convert(int USD, int KRW);
}
ConvertibleWithTwoParams c2 = (USD, KRW) -> System.out.println(USD + "달러 = "+ (USD *KRW) + " 원");
c2.convert(10,1400);

(4) 추상 메서드에 반환 값이 있는 경우

** 반환 {}가 있어도; 작성합니다.

** 추상 메서드에 반환 유형이 있다고 해서 반드시 반환되어야 하는 것은 아닙니다.
= ~~; 람다 식으로 작성합니다.

다음과 같이 리턴을 제거하면 최소한 람다 식은 리턴 옆에 배치합니다.

// int 반환값이 필요한 인터페이스
@FunctionalInterface
public interface ConvertibleWithReturn {
    int convert(int USD, int KRW);
}
//원래 return을 써서 나타내면 {return USD*KRW;}; 로 해야하지만, return을 안 쓰니 {};을 쓸 의무도 사라졌다.
ConvertibleWithReturn c3 = (USD, KRW) -> USD * KRW; int result = c3.convert(20, 1400); System.out.println("20 달러 = "+result+" 원");

4. 직접 해보기

    /*  추상 매소드 인수 1개, 반환형 void 인 경우(함수 경유 나타내기, 그냥 나타내기)
    *   추상 매소드가 인수도 없고 반환형도 void 인 경우
    *   추상 매소드가 인수 2개에  반환형도 있는 경우  */

import WorkOut_Myself.Translator.TranslateEngTo;
import WorkOut_Myself.Translator.TranslateHitoKR;
import WorkOut_Myself.Translator.TranslateTwo;

public class FunctionalInterface_myself {
    public static void main(String() args) {
        TranslateEngTo Hello = (hello) -> System.out.println(hello +"은(는) 한국어로 \"안녕하세요\" 입니다.
"); EngToKR(Hello,"Hi"); EngToKR((Hi) -> System.out.println(Hi +"은(는) 한국어로 \"안녕하세요\" 입니다.
"),"하지메마시테" ); TranslateHitoKR AnyLanguage = () -> System.out.println("Hello는 한국어로 \"안녕하세요.\" 입니다.
"); AnyLanguage.Translate(); TranslateTwo Korean = (ENG, JPN) -> { return "영어인 " + ENG + "은(는) 한국어로 안녕하세요 입니다.
그리고 일본어인 " + JPN + "은(는) 한국어로 안녕하세요 입니다.
"; }; String s = Korean.Translate("Hello!
", "곤니치와"); System.out.println(s); } public static void EngToKR (TranslateEngTo TL, String s){ TL.Translate(s); } }