Language/JAVA

[JAVA] 람다식

inji_ 2023. 8. 27. 22:54

 

1. 람다식이란?

  • 함수형 프로그래밍이란 함수를 정의하고 이 함수를 데이터 처리부로 보내 데이터를 처리하는 기법
  • 데이터 처리부는 데이터만 가지고 있을 뿐, 처리하는 방법이 정해져 있지 않아 외부에서 제공된 함수에 의존한다.
  • 외부에서 제공되는 함수가 람다식이다.
  • 람다식은 익명 클래스 안에 있는 익명 메소드이다.
  • 따라서, 람다식 자체가 메소드이면서 인터페이스를 구현한 객체가 된다. -> 인터페이스의 유일한 추상메소드를 구현한다.
  • 람다식을 사용하면 크게 함수형 인터페이스, 데이터 처리부(메소드 정의), 메소드 호출하여 람다식을 정의하여 사용하는 부분으로 나뉜다.

2. 매개변수가 없는 람다식 예제

package Chapter10;
 
public class ButtonExample {
  public static void main(String[] args) {
    Button btnOk = new Button();
 
    //어차피 함수형 인터페이스를 매개변수로 받는데
    //함수형 매개변수가 들어갈 자리에 람다식을 정의해서 넣으면 함수형 인터페이스에 1개있는 추상형 메소드가 정의되는 것이다.
    //여기서는 설정만해주는 메소드를 실행한 것!
    btnOk.setClickListener(()-> System.out.println("OK버튼을 클릭했습니다."));
    //설정한 것을 실행하는 메소드.
    btnOk.click();
 
    Button btnCancel = new Button();
    btnCancel.setClickListener(()-> System.out.println("Cancel 버튼을 클릭했습니다."));
 
    btnCancel.click();
 
  }
  //익명 함수 장점 : 데이터만 저장해두고 필요할 때마다 메서드를 맘대로 만들어서 사용할 수 있다.
 
}
class Button{
  //함수형 인터페이스 클래스 안에 선언
  public static interface ClickListener{
    void onClick();
  }
  //인터페이스를 필드로 선언
  private ClickListener clickListener;
  //ClickListener타입의 매개변수를 받아서 그 매개변수로 바꿔주는 메소드
  public void setClickListener(ClickListener clickListener) {
    this.clickListener = clickListener;
  }
  //onClick 메소드 실행시켜주는 메소드
  //위에서는 인터페이스에 선언되어 있기만 한거니까 실행시켜주는 메소드가 따로 필요하다.
  public void click(){
    this.clickListener.onClick();
  }
}

① Button 클래스 안에 함수형 인터페이스 ClickListener 선언

② 인터페이스 ClickListener 타입을 필드로 선언

③ Button 클래스 안의 메소드 setClickListener는 ClickListener타입의 매개변수 받아서 그 매개변수로 필드 값 바꿔줌.

④ click 메소드로 인터페이스의 메소드 실행시켜준다.

⑤ Button btnOk = new Button();

-> 객체를 생성한다.

⑥ btnOk.setClickListener(()-> System.out.println("OK버튼을 클릭했습니다."));

-> ()안에 ClickListener의 추상메소드 onClick의 내용을 정의해준다.

-> 람다식은 메소드이면서 인터페이스를 구현한 클래스 객체가 된다.

⑦ btnCancel.click();

-> 람다식으로 정의된 onClick()을 실행시켜주는 Button 객체 안의 click() 메소드를 실행시켜준다.

 

3. 매개변수가 있는 람다식 예제

package Chapter10;
 
public class LambdaEx3 {
  public static void main(String[] args) {
    Person1 person1 = new Person1();
 
    //람다식을 선언하기
 
    person1.action1((name, job) ->
      System.out.println(name+"이 "+job+"을 합니다.")
    );
 
    person1.action2(content -> System.out.println("\""+content+ "\"라고 외칩니다."));
 
  }
}

@FunctionalInterface
interface Workable1{
  void work(String name, String job);
}
 
@FunctionalInterface
interface Speakable{
  void work(String content);
}
class Person1{
  //아래의 메소드는 제공된 람다식을 이용해서 내부 데이터를 처리하는 처리부 역할을 한다.
  //여기서는 함수형 인터페이스에 있는 추상 메서드에 매개변수를 받아와야 하는 작업이 있다.
  //따라서 추상메서드의 매개변수 정보는 action메소드에서 정의해준다.
  public void action1(Workable1 workable){
    workable.work("홍길동","프로그래밍");
  }
 
  //액션 실행하면 매개변수로 받아온 함수형 인터페이스의 work메소드 실행시킴!
  public void action2(Speakable speakable){
    speakable.work("안녕하세요");
  }
}

① action1이 정의된 부분에서는 함수형 인터페이스 Workable1의 메소드 work(String name, String job)를 실행시키는데,

람다식에서 work를 정의하여 실행할 때 필요한 매개변수를 미리 정의해둠으로써, 데이터를 제공한다.

-> 따라서 함수형 인터페이스 Workable1의 메소드 work(String name, String job)의 매개변수 정보를

action메소드에서 정의해준다.

② 람다식은 이미 action 메소드에서 정의된 work 메소드의 매개변수를 어떻게 사용할지 정의하는 역할을 한다.

 

4. 리턴값이 있는 람다식

package Chapter10;
 
//리턴 값이 있는 람다식
public class LambdaEx4 {
  public static void main(String[] args) {
    Person2 person2 = new Person2();
 
    //람다식으로 Calculable안의 추상형 메소드 calc가 할 함수연산을 정의해줌
    person2.action((x,y)->(x+y));
 
    //sum 함수를 정의해서 sum함수에서 연산한 것을 result값으로 넘겨줌!
    person2.action((x,y)->sum2(x,y));
  }
  public static double sum2(double x, double y){
    return (2*(x+y));
  }
 
}
@FunctionalInterface
interface Calculable{
  double cal(double x, double y);
}
class Person2{
  public void action(Calculable calculable){
    double result = calculable.cal(10,4);
    System.out.println("결과 : " +result );
  }
 
}

① 람다식을 통해서 Calculable 인터페이스의 cal 함수를 실행하면 return 값을 결과로 가지도록 설정.

② 따라서 action 함수를 정의할 때, cal 함수의 결과값을 받는 변수를 하나 만들고 그것을 프린트해주도록 따로 만들어야 한다.

③ 또한 메인함수와 같은 클래스에서 sum2 함수를 따로 정의하고 람다식 내에서 리턴값을 sum2함수를 사용해서 간단하게 표기하여 return값으로 넘겨줄 수도 있다.

5. 람다식의 장점

① 람다식을 통해 1회성의 익명의 함수를 만들기 때문에,

함수를 한 번만 사용할 때 용이하다.

② 데이터 처리부에서 데이터를 보관하고 있기 때문에,

원하는 상황에 따라 함수만 정의하면 되기 때문에 가변성이 좋다.

③ 코드를 간결하게 만들 수 있고, 가독성이 높아진다.

'Language > JAVA' 카테고리의 다른 글

[JAVA]HashMap에서 hashCode(),eqauls() 오버라이딩  (0) 2023.08.27
[JAVA] Generic  (0) 2023.08.27