Java ‐ 람다 - dnwls16071/Backend_Study_TIL GitHub Wiki
📚 람다가 필요한 이유
- 중복을 제거하고 좋은 코드를 유지하는 핵심은 변하는 부분과 변하지 않는 부분을 분리하는 것
- 값 매개변수화(=동적 파라미터 전달)
📚 람다 정의
- 자바 8부터 도입된 람다는 자바에서 함수형 프로그래밍을 지원하기 위한 기능이다.
- 람다는 익명 함수로 분류되기 때문에 이름 없이 함수를 표현한다.
📚 함수형 인터페이스
- 정확히 하나의 추상 메서드를 가지는 인터페이스를 말한다.
- 람다는 추상 메서드가 하나인 함수형 인터페이스에만 할당할 수 있다.
- 단일 추상 메서드를 줄여서 SAM(Single Abstract Method)라고 한다.
- 람다를 사용할 인터페이스라면 클래스 상단에
@FunctionalInterface
어노테이션을 달아두는 것을 권장한다.
📚 람다와 생략
@FunctionalInterface
public interface MyFunction {
int apply(int a, int b);
}
public class Main {
public static void main(String[] args) {
// Ex1
MyFunction myFunction1 = (int a, int b) -> {
return a + b;
};
System.out.println(myFunction1.apply(1, 2));
// Ex2
MyFunction myFunction2 = (int a, int b) -> a + b;
System.out.println(myFunction2.apply(3, 4));
// Ex3
MyFunction myFunction3 = (int a, int b) -> {
System.out.println("Lambda Expression");
return a + b;
};
System.out.println(myFunction3.apply(5, 6));
// Ex4
MyFunction myFunction = (a, b) -> {
System.out.println("hello Lambda with parameters: " + a + ", " + b);
return a + b;
};
System.out.println(myFunction.apply(10, 20));
}
}
@FunctionalInterface
public interface Procedure {
void run();
}
public class ProcedureMain {
public static void main(String[] args) {
// Ex1
Procedure procedure1 = () -> {
System.out.println("hello Lambda!");
};
procedure1.run();
// Ex2
Procedure procedure2 = () -> System.out.println("hello Lambda!");
procedure2.run();
}
}
- 매개변수 타입 : 생략 가능, 그러나 필요하다면 명시적으로 작성
- 반환 타입 : 문법적으로 명시할 수 없고 식 결과를 보고 컴파일러가 항상 추론한다.
- 람다는 보통 간결하게 사용하는 것을 권장
- 단일 표현식이라면 중괄호와 리턴은 생략해라.
- 타입 추론을 통해 매개변수 타입을 생략해라.
📚 람다의 전달
public class LambdaPass {
public static void main(String[] args) {
MyFunction addFunction = getOperation("+");
System.out.println("Result: " + addFunction.apply(5, 3));
MyFunction subtractFunction = getOperation("-");
System.out.println("Result: " + subtractFunction.apply(5, 3));
MyFunction multiplyFunction = getOperation("*");
System.out.println("Result: " + multiplyFunction.apply(5, 3));
MyFunction divideFunction = getOperation("/");
System.out.println("Result: " + divideFunction.apply(5, 3));
}
static MyFunction getOperation(String operator) {
switch (operator) {
case "+":
return (a, b) -> a + b;
case "-":
return (a, b) -> a - b;
case "*":
return (a, b) -> a * b;
case "/":
return (a, b) -> {
if (b == 0) {
throw new IllegalArgumentException("Division by zero is not allowed.");
}
return a / b;
};
default:
throw new IllegalArgumentException("Invalid operator: " + operator);
}
}
}
📚 고차 함수
- 람다는 함수형 인터페이스를 구현한 익명 클래스와 같은 개념으로 이해하면 된다.
- 람다를 변수에 대입한다는 것은 람다 인스턴스의 참조값을 대입하는 것이고 람다를 메서드의 매개변수나 반환값으로 넘긴다는 것 역시 람다 인스턴스 참조값을 넘긴다는 것과 같다.
- 람다를 변수에 대입, 람다는 메서드 매개변수에 전달, 람다를 메서드에서 반환하는 것 모두 가능하다.
[고차 함수(Higher-Order Function)]
- 함수(람다)를 인자로 받는 함수
- 함수(람다)를 반환하는 함수
static void calculate(MyFunction function) {
// ...
}
static MyFunction getOperation(String operator) {
// ...
return (a, b) -> a + b;
}