람다가 필요한 이유
#Java/adv3
람다가 필요한 이유1
변하지 않는 부분과 변하는 부분을 분리하여, 변하지 않는 부분은 유지하고 변하는 부분은 매개변수(파라미터)를 통해 외부에서 전달받도록 한다.
- 프로그래밍에서 중복을 제거하고, 좋은 코드를 유지하는 핵심은 변하는 부분과 변하지 않는 부분을 분리하는 것
“Hello Spring”
과 같은 구체적인 값(Value)을 매개변수를 통해 외부에서 전달받아 메서드의 동작을 달리하고, 재사용성을 높이는 방법을 값 매개변수화(Value Parameterization)라 한다.
람다가 필요한 이유2
어떠한 동작의 실행 시간을 측정하는 메서드 두 개 하나의 메서드에서 실행되도록 리팩토링하려면, 문자열 같은 단순한 값이 아니라 코드 조각을 전달해야 한다.
- 두 메서드에서 시간을 측정하고, 시간을 출력하는 부분은 변하지 않는 부분이다.
- 코드 조각을 시작하고 종료하는 부분을 외부에서 전달받아야 한다.
- 지금까지 배운 내용으로 메서드를 전달하는 방법은 없다.
- 코드 조각은 클래스 내부에 위치하는 메서드에 정의한다. 인스턴스를 전달하고, 인스턴스의 메서드를 호출하자.
- 다형성을 활용하여 전달되는 인스턴스에 따라 다른 코드 조각이 실행된다.
package lambda;
public interface Procedure {
void run();
}
// 정적 중첩 클래스 사용
public class Ex1RefMainV1 {
public static void hello(Procedure procedure) {
long startNs = System.nanoTime();
//코드 조각 시작
procedure.run();
//코드 조각 종료
long endNs = System.nanoTime();
System.out.println("실행 시간: " + (endNs - startNs) + "ns");
}
static class Dice implements Procedure {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
}
static class Sum implements Procedure {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
}
}
public static void main(String[] args) {
Procedure dice = new Dice();
Procedure sum = new Sum();
hello(dice);
hello(sum);
}
}
코드 조각을 메서드에 전달할 때는 인스턴스를 전달하고 해당 인스턴스에 있는 메서드를 호출하면 된다.
- /동작 매개변수화(Behavior Parameterization)
- 코드 조각(코드의 동작 방법, 로직, Behavior)을 메서드(함수) 안에 두는 것이 아니라, 매개변수(파라미터)를 통해서 외부에서 전달 받도록 해서, 메서드의 동작을 달리하고, 재사용성을 높이는 방법을 동작 매개변수화라 한다.
- 동작 매개변수화, 동작 파라미터화, 행동 매개변수화(파라미터화), 행위 파라미터화 등으로 부른다.
람다가 필요한 이유3
Procedure dice = new Procedure() {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
};
psvm {
hello(dice);
}
- /익명 클래스 사용2 - 참조값 직접 전달: 참조값을 지역변수에 담아두지 않고 매개변수에 직접 전달
hello(new Procedure() {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
});
- /람다(lambda)
- 값 파라미터화, 동작 파라미터화 모두 결국에는 메서드에 인수로 전달할 수 있는 것은 간단한 값이나 인스턴스 참조이다.
- 코드 조각을 전달하기 위해 클래스를 정의하고 메서드를 만들고 또 인스턴스까지 생성하는 복잡한 과정을 거쳐야 할까?
- 클래스 만들고 메서드 만들고 인스턴스 만드는 과정을 생략하고, 아래와 같이 코드 조각만 전달할 수는 없을까?
hello({ // 랜덤 값을 출력하는 코드 블럭
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
});
hello(() -> {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
});
new Procedure() {
부터 @override public void run()
에서 파라미터()
앞까지 지워버리고,()
뒤에 ->
를 추가해준다.
뒤에 있는 }
도 지워준다.
- 람다를 사용한 코드를 보면 클래스나 인스턴스를 정의하지 않고, 매우 간편하게 코드 블럭을 직접 정의하고, 전달하는 것을 확인할 수 있다.
함수 vs 메서드
람다는 함수이다. 함수와 메서드의 차이에 대해 알아보자.
- 함수와 메서드에 대해서는 일반적으로 객체지향 프로그래밍(OOP) 관점에서 다음과 같은 차이가 있다
- 함수(Function)
- 독립적으로 존재하며, 클래스(객체)와 직접적인 연관이 없다.
- 객체지향 언어가 아닌 C 등의 절차적 언어에서는 모든 로직이 함수 단위로 구성된다.
- 객체지향 언어라 하더라도, 예를 들어 Python이나 JavaScript처럼 클래스 밖에서도 정의할 수 있는 "함수" 개념을 지원하는 경우, 이를 그냥 함수라고 부른다.
- 호출 방식
- 호출 시에 객체 인스턴스가 필요 없고, 보통
이름(매개변수)
형태로 호출된다. - 지역 변수, 전역 변수 등과 함께 동작하며, 클래스나 객체 특유의 속성(인스턴스 변수 등)은 다루지 못한다.
- 호출 시에 객체 인스턴스가 필요 없고, 보통
- 함수는 클래스(객체)와 상관없이, 독립적으로 호출 가능한 로직의 단위이다.
- 메서드(Method)
- 클래스(또는 객체)에 속해 있는 "함수"이며, 객체의 상태와 밀접한 관련이 있다.
- 객체의 상태(필드, 프로퍼티 등)에 직접 접근하거나, 객체가 제공해야 할 기능을 구현할 수 있다.
- Java, C++, C#, Python 등 대부분의 객체지향 언어에서 클래스 내부에 정의된 함수는 보통 "메서드"라고 부른다.
- 호출 방식
- 보통
객체(인스턴스).메서드이름(매개변수)
형태로 호출한다. - 호출될 때, 해당 객체의 필드(속성)나 다른 메서드에 접근 가능하며, 이를 이용해 로직을 수행한다.
- 인스턴스 메서드, 클래스(정적) 메서드, 추상 메서드 등 다양한 형태가 있을 수 있다.
- 보통
람다 시작
Procedure procedure = () -> {
System.out.println("hello! lambda");
};
procedure.run();
- 람다는
() -> {}
와 같이 표현한다.()
부분이 메서드의 매개변수라 생각하면 되고,{}
부분이 코드 조각이 들어가는 본문이다. - 람다를 사용할 때는 이름, 반환 타입은 생략하고, 매개변수와 본문만 간단하게 적으면 된다.
(매개변수) -> { 본문 }
, 여기서는 매개변수가 없으므로() -> {본문}
- 쉽게 이야기해서 익명 클래스를 만들기 위한 모든 부분을 생략하고, 꼭 필요한 매개변수와 본문만 작성하면 된다.
MyFunction myFunction = (int a, int b) -> {
return a + b;
};
int result = myFunction.apply(1, 2);
System.out.println("result = " + result);
- 이번에는 매개변수가 있으므로
(int a, int b) -> {본문}
과 같이 작성하면 된다.
'Java > Modern Java(8~)' 카테고리의 다른 글
[Java] 62. 메서드 참조 (0) | 2025.07.04 |
---|---|
[Java] 61. 람다 vs 익명 클래스 (0) | 2025.07.04 |
[Java] 60. 람다 활용 (0) | 2025.07.04 |
[Java] 59. 함수형 인터페이스 (0) | 2025.07.04 |
[Java] 58. 람다 (0) | 2025.07.04 |