1. 람다식
(1) 정의
익명함수 (이름이 없는 함수) == 접근제어자, 반환형, 함수이름, 파라미터의 자료형 다 필요 없음.
람다식도 일급 객체이다.
**일급 객체란?
데이터나 변수를 받을 수 있는 객체, 어떤 매소드의 파라미터로 들어갈 수 있는 객체, 어떤 매소드의 반환 값이 될 수 있는 객체 이다.
(2) 형태
(전달값 1, 전달값2, ...) -> { 실행코드 }
2. 함수형 인터페이스
(1) 뜻
추상 매소드가 오직 하나 뿐인 인터페이스
(2)람다식과의 관계
람다식은 오직 함수형 인터페이스로만 접근 가능.
** why?
인터페이스에 추상 매소드가 두 개이면, 람다식과 매칭되는 추상 매소드가 무엇인지 모호해진다.
따라서 추상 매소드가 오직 하나인 함수형 인터페이스만이 람다식과 매칭이 가능하여 쓸 수 있다.
(둘 사이의 파라미터 갯수, 리턴값 유무는 맞춰야 한다.)
3. 코드 리뷰
(1) 추상 매소드에 인수 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) 추상 매소드에 인수 없고, 반환형도 void인 경우
// 함수형 인터페이스
@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) 추상 매소드에 인수가 2개 이상인 경우 반환형은 void
** 둘이 인수 갯수 맞춰주면 됨.
public interface ConvertibleWithTwoParams {
void convert(int USD, int KRW);
}
ConvertibleWithTwoParams c2 = (USD, KRW) -> System.out.println(USD + "달러 = "+ (USD *KRW) + " 원");
c2.convert(10,1400);
(4) 추상 매소드에 반환 값이 있는 경우
** return이 있는 경우에도 {};을 꼭 써줘야 한다.
** 추상 매소드가 반환형 갖는다고 해서 람다식에 꼭 return = ~~;를 써줄 필요는 없다.
밑의 경우처럼 그냥 return 빼고 적어도 람다식이 알아서 return 옆에 꽂아 넣는다.
// 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);
}
}
'Language > Java' 카테고리의 다른 글
[JAVA] Stream 실습 (0) | 2023.02.19 |
---|---|
[JAVA] Stream (0) | 2023.02.18 |
[JAVA] 익명 클래스 (0) | 2023.02.15 |
[JAVA] Iterator (0) | 2023.02.15 |
[JAVA] HashMap (0) | 2023.02.13 |