lambda-expression (람다 표현식)
Java 8 버전부터 도입된 것으로, 추상 메소드가 하나인 인터페이스 구현 시 간략화된 표현이 가능하다.
익명 클래스 사용 시 더 간략화하여 표현이 가능한 것이다.
람다 표현식은
() -> {}
와 같은 형태로 사용한다.
💻 Java 예제
1. 인터페이스를 구현하는 클래스
2. 익명 클래스
3. 람다 표현식 (lambda expression)
총 세 가지 방법을 이용해서 매개변수로 들어온 두 값을 더해 리턴하는 add() 함수를 만들어본다.
📝 소스 코드
public class Main {
public static void main(String[] args) {
System.out.println("[1] 인터페이스를 구현하는 클래스");
Addable myAdder = new AdderImple();
double result = myAdder.add(1.11, 2.22);
System.out.println("result = " + result);
System.out.println("\n[2] 익명 클래스 사용");
Addable myAdder2 = new Addable() {
@Override
public double add(double x, double y) {
return x + y;
}
};
System.out.println("result = " + myAdder2.add(1.11, 2.22));
System.out.println("\n[3] 람다 표현식(lambda expression) 사용");
Addable myAdder3 = (x, y) -> x + y;
result = myAdder3.add(1.11, 2.22);
System.out.println("result = " + result);
}
}
interface Addable { // 인터페이스
public abstract double add(double x, double y);
}
class AdderImple implements Addable { // 인터페이스를 구현하는 클래스
@Override
public double add(double x, double y) {
return x + y;
}
}
아래에 Addable이라는 인터페이스를 생성하고, 해당 인터페이스를 구현하는 AdderImple 클래스를 만들었다.
클래스 내에서 double add(double x, double y) 메소드를 구현하였다.
[1] 첫 번째로 Addable 인터페이스를 구현한 AdderImple 클래스를 사용해 두 수의 덧셈을 해본다.
Addable 타입으로 AdderImple 객체를 생성하고, 생성한 객체에서 add() 메소드를 호출하여 두 수를 더한다.
[2] 두 번째는 익명 클래스 사용이다.
[1] 방법과는 달리 AdderImple라는 클래스를 사용해 객체를 생성하지 않았다.
Addable() 객체를 바로 생성하고 해당 객체 내에 바로 메소드를 생성하였다.
따로 명시된 클래스 이름이 없으므로 익명 클래스라 하는 것이다.
[3] 세 번째는 람다 표현식을 사용한 것이다.
소괄호 () 안에는 함수에서 사용할 매개변수가 들어가고 -> 뒤에는 리턴 값 또는 수행할 코드를 작성한다.
위 소스 코드에서 () 안 매개변수 x와 y를 명시하였고, -> 뒤는 x + y로 리턴 값을 명시해준 것이다.
람다 표현식을 사용하지 않은 경우 인터페이스를 구현한 클래스 객체를 생성하거나, 익명 클래스를 사용해야 했다.
람다 표현식를 사용함으로써 클래스를 명시하지 않아도 되고, 클래스 내 메소드도 모든 내용을 쓰지 않고 간편한 표현으로 메소드를 만들어 사용할 수 있다.
코드가 좀 더 간결해지고, 직관성을 띄게 된다.
📄 실행 결과
다양한 람다 표현식
매개변수가 없거나 있는 것과 리턴 값이 없거나 있는 경우의 다양한 람다 표현식 예제를 만들어본다.
매개변수 타입은 생략해서 표현이 가능한데 만약 매개변수가 여러 개 있는 경우,
모든 매개변수의 타입을 생략해서 표현하거나 모든 매개변수 타입의 모두 다 표현해야 한다.
💻 Java 예제
📝 소스 코드
public class Main {
public static void main(String[] args) {
// 매개변수, 리턴 값 없는 경우
Test01 lambda01 = () -> System.out.println("안녕하세요");
lambda01.testPrint();
System.out.println();
// 매개변수 한 개, 리턴 값 없는 경우
Test02 lambda02 = (x) -> System.out.println("num = " + x);
lambda02.testPrint(55);
System.out.println();
// 매개변수 여러 개, 리턴 값 있음
Test03 lambda03 = (x, y) -> (x > y) ? x : y;
System.out.println("result = " + lambda03.max(10, 20));
System.out.println();
// 매개변수 한 개, 내부 수행코드 여러 줄, 리턴 값 있음
Test04 lambda04 = (x) -> {
System.out.println(x);
return x.length();
};
int result = lambda04.myStrLen("Java");
System.out.println("result = " + result);
System.out.println();
// void printMax(double x, double y)
// [출력 양식]
// x = 3.14
// y = 1.2
// (3.14 > 1.2) => 둘 중 큰 값 리턴
Test05 lambda05 = (x, y) -> {
System.out.println("x = " + x);
System.out.println("y = " + y);
System.out.println((x > y) ? x : y);
};
lambda05.printMax(3.14, 1.2);
System.out.println();
System.out.println(lambda05);
}
}
interface Test01 {
// 매개변수, 리턴 값 없음
public abstract void testPrint();
}
interface Test02 {
// 매개변수 한 개, 리턴 값 없음
public abstract void testPrint(int num);
}
interface Test03 {
// 매개변수 여러 개(2), 리턴 값 int형
public abstract int max(int n1, int n2);
}
interface Test04 {
// 매개변수 한 개, 리턴 값 int형
public abstract int myStrLen(String str);
}
interface Test05 {
// 매개변수 여러 개(2), 리턴 값 없음
public abstract void printMax(double x, double y);
}
Test01 인터페이스를 구현한 lambda01은 매개변수와 리턴 값 모두 없다.
따라서 ()안에 매개변수가 없고, -> 뒤의 코드만 수행하여 안녕하세요를 출력하는 추상 메소드를 만들었다.
Test02 인터페이스를 구현한 lambda02에서는 매개변수 한 개를 받아온다.
x라는 이름으로 매개변수 값을 받아오고, 그 x를 수행할 코드에서 사용할 수 있다.
Test03 인터페이스를 구현한 lambda03에서는 두 개의 매개변수 값을 받아오고 int 타입을 리턴한다.
이때 람다 표현식에는 삼항 연산자를 사용하였다.
매개변수로 받은 두 값을 비교하고 x가 크면 x가 리턴되고, y가 크면 y가 리턴된다.
Test04 인터페이스를 구현한 lambda04에서는 매개변수가 한 개다.
그리고 중괄호 {}를 사용하여 수행할 코드 여러 줄을 작성해주었다.
print 함수를 이용해 매개변수로 들어온 값을 출력하고, 매개변수 값의 길이를 리턴한다.
Test05 인터페이스를 구현한 lambda05에서는 매개변수가 두 개이고, 리턴 값은 없다.
수행할 코드를 여러 줄 넣었다. 입력받은 매개변수 값을 출력하고, 두 값을 비교하여 x 값이 크면 x를 출력하고, y 값이 크면 y를 출력하게 하였다.
위와 같이 다양한 방식으로 람다 표현식을 사용할 수 있다.
📄 실행 결과
lambda 표현식은 익명이므로 이름이 존재하지 않는다.
그래서 System.out.println(lambda5); 코드를 실행하였을 때 클래스 이름 같은 게 뚜렷하게 나오지 않고, lambda5가 위치해있는 값이 나오는 것이다.
위 Java 예제 코드는 편의상 패키지를 default로 두고, 클래스명 또한 바꾼 것이기 때문에
lambda05를 출력했을 때 위 실행 결과와는 다른 값이 뜨게 될 것이다.