람다식

조상원·2025년 8월 2일

JAVA

목록 보기
32/34
  • Lambda Expressions
  • 자바에서 함수적 프로그래밍을 위해 자바8부터 람다식을 지원
  • 매개변수를 가지는 함수와 같은 코드 블록이지만 런타임 시에는 인터페이스의 익명 구현 객체를 생성
  • 코드가 간결해짐
  • 컬렉션의 요소들을 필터링하거나 매핑해서 원하는 결과를 쉽게 가져올 수 있음
  ([자료형 매개변수, ...]) -> {
  	// 실행 코드
  
  	[return 반환값;]
  };
예시)
            () -> { ... }
            (int a) -> { System.out.println(a); }
            (a) -> { System.out.println(a); }
            a -> System.out.println(a);
            (int a, int b) -> { return a + b; }
            (a, b) -> { return a + b; }
            (a, b) -> a + b;

함수적 인터페이스

Functional Interface

  • 람다식은 인터페이스 타입의 변수에 대입된다
  • 람다식은 인터페이스의 익명 구현 객체를 생성
  • 하나의 추상 메소드가 선언된 인터페이스만 람다식으로 익명 구현 객체를 생성할 수 있음 : 함수적 인터페이스
  • 함수적 인터페이스를 선언할 때 @FunctionalInterface 어노테이션을 붙이면 두 개 이상의 추상메소드가 선언되지 않도록 컴파일러가 체크해 준다.(생략해도 OK)
@FunctionalInterface
public interface Runnable {

  public abstract void run();
}

//람다식에서 필드와 지역 변수 사용하기
    private int number = 100;
    public void method4(int arg){
        int number = 200;
        A_Functional fi;

        //람다식에서 지역 변수를 사용할 때는 final, 유사 final이어야 한다
        //  - 지역변수는 람다식에서 읽는 것은 허용되지만, 람다식 내부 또는 외부에서 변경할 수 없다.
        //  - 초기화된 이후에 값을 한번도 변경되지 않는 변수를 유사 final이라고 한다
//        arg = 600;
//        number = 500;
        this.number = 400;
        //람다식에서 사용하는 this는 람다식을 실행하는 객체의 참조이다.
        //람다식은 외부 클래스에서 실행되므로 this는 람다식이 포함된 외부 클래스 객체의 참조를 의미한다
        fi = () -> {
            System.out.println(arg);            //300
            System.out.println(number);         //200
            System.out.println(this.number);    //100
        };
        fi.execute();

        //익명 구현 객체에서 사용되는 this는 익명 구현 객체로 생성된 객체의 참조이다
        fi = new A_Functional() {
            @Override
            public void execute() {
                System.out.println(arg);
                System.out.println(number);
//                System.out.println(this.number);
            }
        };
        fi.execute();
    }

표준 함수적 인터페이스

  • 자바 8부터 빈번히 사용되는 함수적 인터페이스는 java.util.function 표준 API 패키지로 제공된다.
  • 표준 함수적 인터페이스는 용도에 따라 크게 Consumer, Supplier, Function, Operator, Predicate로 구분된다.
@FunctionalInterface
public interface Consumer<T> {

  void accept(T t);
}

@FunctionalInterface
public interface Supplier<T> {

  T get();
}

@FunctionalInterface
public interface Function<T, R> {

  R apply(T t);
}

@FunctionalInterface
public interface IntBinaryOperator {

  int applyAsInt(int left, int right);
}

@FunctionalInterface
public interface Predicate<T> {

  boolean test(T t);
}

0개의 댓글