Java의 기본 개념 중 Lamda에 대해 알아보자.
람다 함수는 익명 함수(Anonymous functions)를 의미하며, 기본꼴은 ()->{}이다.
람다의 규칙 3가지를 이해하면
1. 람다는 매개변수 / 화살표(->) / 함수몸체
로 사용 가능
2. 함수몸체가 단일 실행문이면 괄호{} 생략 가능
3. 함수몸체가 return문으로만 구성되어 있는 경우 괄호{} 생략 불가
아래의 코드를 천천히 이해해보자.
interface Test01{
void f1();
}
interface Test02 {
void f1(int num);
}
interface Test03 {
void f1(int num, String s);
}
interface Test04 {
int f1();
}
interface Test05 {
int f1(int num);
}
위와 같이 인수와 return 타입이 다른 5가지의 interface를 구현해보며 람다식을 적용해보자.
public class HelloApplication {
public static void main(String[] args) {
Test01 t1 = new Test01() {
@Override
public void f1() {
System.out.println(1);
}
};
t1.f1();
// 위의 코드를 람다 식으로 표현하기
// Test t2 = () -> {}: 람다의 기본 꼴
Test01 t2 = () -> {
System.out.println(2);
};
t2.f1();
위 2가지의 결과가 동일하다.
람다를 활용하면, 간단하게 코드를 작성할 수 있다.
//인수가 있을 때 람다 사용법
//Test02 t3 = (n) -> {
// System.out.println(n);
//};
//인수 전달이 1개 전달 일때만... ()를 생랼할 수 있다.
//일반적으로 생략한다.
Test02 t3 = n -> {System.out.println(n);};
t3.f1(100);
//인수 전달이 2개여서 ()를 생략할 수 없다.
Test03 t4 = (n, s) -> {
System.out.println(n+s);
};
t4.f1(100, "호랑이");
위의 코드는 interface에 인수가 있는 경우이다.
인수가 1개인 경우에만 ()를 생략할 수 있다.
//return 값이 있는 경우
//Test04 t5 = ()->{
// return 1000;
//};
//한 문장일 때는 return과 {} 생략 가능, 선호됨
Test04 t5 = ()->1000;
System.out.println(t5.f1());
//return값, 인수가 있는 경우
Test05 t6 = n -> n*2;
System.out.println(t6.f1(100));
}
}
위의 코드는 interface에 return값이 있는 경우이다.
단문장인 경우 return과 {}을 생략할 수 있고,
인수가 1개인 경우에는 ()을 생략할 수 있기 때문에 코드가 굉장히 간단해진다.
interface Test01{
void f1();
}
interface Test02{
int f1();
}
class Tiger {
void f2(Test01 ttt){
ttt.f1();
}
void f3(Test02 ttt) {
System.out.println(ttt.f1());
}
}
public class HelloApplication {
public static void main(String[] args) {
Test01 t1 = ()->{
System.out.println(1);
};
t1.f1();
Test02 t2 = ()-> 100;
System.out.println(t2.f1());
Tiger t = new Tiger();
//원래 코드
t.f2(new Test01() {
@Override
public void f1() {
System.out.println("확인1");
}
});
//람다사용
t.f2(()->{
System.out.println("확인2");
});
//원래 코드
t.f3(new Test02() {
@Override
public int f1() {
System.out.println("확인3");
return 100;
}
});
//람다사용
t.f3(()->100);
}
}
위 코드를 살펴보면 람다를 사용할 때 코드가 훨씬 간편해짐을 확인할 수 있다.
만약 이해가 잘 되지 않는다면, 앞 부분부터 한번 더 읽고 오기를 추천한다.
처음에는 낯설 수 있지만, 한번 이해하면 매우 편리하게 사용 가능할 것이다.
여기까지 잘 이해했다면, 아래의 코드를 한번 살펴보자.
interface Test01{
void f1();
}
class Tiger{
Test01 f2(Test01 t){
return ()->{
System.out.println(2);
};
}
}
public class HelloApplication {
public static void main(String[] args) {
Tiger t = new Tiger();
t.f2(()->{
System.out.println(1);
}).f1();
}
}
main을 살펴보면, Tiger 객체를 생성하고, f2()를 호출한다.
f2()는 Test01 객체를 인수로 받기 때문에 람다를 활용해 익명의 Test01 객체를 생성하였음을 알 수 있다.
또한 Test01는 interface로 f1()을 반드시 구현해주어야 한다.
따라서 위와 같은 코드가 나오게 된 것이다.
interface Test01{
int f1(int num);
}
class Tiger{
Test01 f2(Test01 t){
t.f1(88);
return n-> 77;
}
}
public class HelloApplication {
public static void main(String[] args) {
Tiger t = new Tiger();
t.f2(n-> 66).f1(99);
}
}
위의 코드가 이해된다면, 람다를 잘 이해했다고 볼 수 있다!