함수형 인터페이스와 람다

이연중·2021년 1월 29일
0

JAVA

목록 보기
8/20

함수형 인터페이스와 람다식

함수형 인터페이스(Functional Interface)

  • 추상 메소드를 하나만 가지고 있는 인터페이스, 위반시 컴파일 에러
  • SAM(Single Abstract Method) 인터페이스
  • @FunctionalInterface 애노테이션을 가지고 있는 인터페이스
  • static, default 메소드 등 다른 메서드 있어도 상관없음

람다 표현식(Lambda Expressions)

  • 함수형 인터페이스의 인스턴스를 만드는 방법으로 쓰일 수 있음
  • 코드를 줄일 수 있음(Fn + Enter in InteliJ)
  • 메소드 매개변수, 리턴 타입, 변수로 만들어 사용 가능(함수형 인터페이스를 inline으로 구현한 오브젝트이기 때문)

자바에서의 함수형 프로그래밍

  • 함수형 인터페이스와 람다 표현식은 자바에서 함수형 프로그래밍을 하는 초석이 된다

  • 함수를 First Class Object로 사용할 수 있음(함수처럼 생긴 특수한 오브젝트,람다식의 결과를 메서드 파라미터에 전달, 리턴 가능)

  • 순수 함수(Pure Function)

    • 사이트 이펙트를 만들 수 없음(함수 내부에 있는 값, 파라미터로 전달받은 값만 사용할 수 있음. 함수 밖에 있는 값 변경 불가)
    • 상태가 없다(함수 밖에 정의되어 있는 변수)
  • 고차 함수(High-Order Function)

    • 함수가 함수를 매개변수로 받을 수 있고 함수를 리턴할 수도 있음
  • 불변성

자바에서 제공하는 함수형 인터페이스

람다식으로 만든 객체에 접근하기 위해 함수형 인터페이스를 사용한다. 그렇다면 람다식을 사용할 때마다 함수형 인터페이스를 정의해야 한다는 것인데, 자바에서는 이러한 불편함의 해소를 위해 라이브러리를 제공한다.

Java가 기본으로 제공하는 함수형 인터페이스

Function<T,R>

  • T 타입을 받아서 R 타입을 리턴하는 함수 인터페이스

    • R apply(T t)
  • 함수 조합용 메소드

    • andThen
    • compose
  • 예)

    Function<Integer, Integer> plus10 = (i) -> i + 10;
    
    Function<Integer, Integer> multiply2 = (i) -> i*2;
    
    Function<Integer, Integer> multiply2AndPlus10 = plus10.compose(multiply2);
    
    System.out.println(multiply2AndPlus10.apply(2)); // 14출력! 
    
    System.out.println(plus10.andThen(multiply2).apply(2)); //24출력!

BiFunction<T, U, R>

  • 두 개의 값(T,U)를 받아서 R 타입을 리턴하는 함수 인터페이스
    • R apply(T t, U u)

Consumer

  • T 타입을 받아서 아무것도 리턴하지 않는 함수 인터페이스
    • void Accept(T t)
  • 함수 조합용 메소드
    • andThen

Supplier

  • T 타입의 값을 제공하는 함수 인터페이스. 값을 받아옴(입력값 x)
    • T get()

Predicate

  • T 타입을 받아서 boolean을 리턴하는 함수 인터페이스
    • boolean test(T t)
  • 함수 조합용 메소드
    • And
    • Or
    • Negate

UnaryOperator

  • Function<T, R>의 특수한 형태로, 입력값 하나를 받아서 동일한 타입을 리턴하는 함수 인터페이스(입력값이 하나이고, 입력값의 타입과 결과값의 타입이 같은 경우)

BinaryOperator

  • BiFunction<T, U, R>의 특수한 형태로, 동일한 타입의 입력값 두개를 받아 리턴하는 함수 인터페이스

람다 표현식

람다

  • (인자 리스트) -> {바디}

인자 리스트

  • 인자가 없을 때: ()
  • 인자가 한개일 때: (one) 또는 one
  • 인자가 여러개 일 때: (one, two)
  • 인자의 타입은 생략 가능. 컴파일러가 추론 하지만 명시할 수도 있음

바디

  • 화살표 오른쪽에 함수 본문을 정의
  • 여러 줄인 경우 {}를 사용해 묶음
  • 한 줄인 경우엔 생략 가능. return도 생략 가능

변수 캡쳐(Variable Capture)

  • 로컬 변수 캡쳐
    • final이거나 effectivce final인 경우에만 참조 가능
    • 그렇지 않은 경우 concurrency 문제가 생길 수 있어 컴파일러가 방지
  • effective final
    • 사실상 final인 변수
    • 자바 8부터 final 키워드를 사용하지 않은 변수를 익명 클래스 구현체 또는 람다에서 참조할 수 있음
  • 익명 클래스 구현체와 달리 "쉐도윙"하지 않음
    • 익명 클래스는 새로 scope를 만들지만, 람다는 람다를 감싸고 있는 scope와 같음

메소드 레퍼런스

람다는 기존 메소드 또는 생성자를 호출 하는 일을 한다면, 메소드 레퍼런스를 사용해서 매우 간결하게 표현할 수 있다.

  • 메소드 또는 생성자의 매개변수로 람다의 입력값을 받음
  • 리턴값 또는 생성한 객체는 람다의 리턴값

참고

https://www.inflearn.com/course/the-java-java8

profile
Always's Archives

0개의 댓글