[Java 8] 함수형 인터페이스와 람다

홍정완·2022년 5월 26일
0

Java

목록 보기
1/25
post-thumbnail

자바 8 소개


  • 2014년 3월 출시, 2020년 기준 83%의 점유율

  • LTS(오랜 기간 업데이트를 제공) / 자바 11도 LTS

  • Non-LTS의 경우 다음 버전 출시 시(약 6개월 주기) 업데이트 ❌




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


  • 추상 메서드를 딱 하나만 가지고 있는 SAM (Single Abstract Method) 인터페이스

  • static/default 메서드는 있어도 가능

  • @FuncationInterface 애노테이션을 가지고 있는 인터페이스

    • 함수형 인터페이스를 더 견고하게 관리할 수 있다. (위반 시 컴파일 에러)

@FunctionalInterface 
public interface RunSomething {

    void doIt();

    static void printName() {
        System.out.println("Hong");
    }

    default void printAge() {
        System.out.println("25");
    }

}



람다 표현식 (Lambda Expressions)


  • 함수형 인터페이스의 인스턴스를 만드는 방법으로 쓰임, 코드를 줄일 수 있다

  • 메서드 매개변수, 리턴 타입, 변수로 만들어 사용 가능


    // 자바 8 이전
    public static void main(String[] args) {
        
        // 익명 내부 클래스 (anonymous inner class), 자바 8이전
        RunSomething runSomething1 = new RunSomething() {
            @Override
            public void doIt() {
                System.out.println("Hello");
            }
        };

		//여기부터 자바 8
        RunSomething runSomething2 = () -> System.out.println("Hello");

        RunSomething runSomething3 = Foo::doIt;

        RunSomething runSomething4 = () -> {
            System.out.println("Hello");
            System.out.printf("Hong");
        };

        runSomething1.doIt();
        runSomething2.doIt();
        runSomething3.doIt();
        runSomething4.doIt();
    }

    private static void doIt() {
        System.out.println("Hello");
    }



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



함수형 프로그래밍은 다음 조건을 만족해야 한다.

  1. 일급 객체 (First Class Object)
  2. 순수 함수 (Pure function)
  3. 고차 함수 (Higher-Order Function)
  4. 불변성



함수를 First class object로 사용할 수 있다.


  • 파라미터로 전달 가능
  • return 값으로 사용 가능
  • 변수 or 데이터 구조에 담기 가능

과거 자바에서 Method는 변수에 담을 수 없었다.
모던 자바에서는 가능해짐. 함수를 하나의 객체로 취급



순수 함수 (Pure function)


  • 사이드 이펙트가 없다 (함수 밖에 있는 값을 변경하지 않는다)

  • 상태가 없다 (함수 밖에 있는 값을 사용하지 않는다)



  • 입력받은 값이 동일한 경우, 결과값이 같아야 한다 ✅
    @FunctionalInterface
    public interface RunSomthing {
        int doIt(int number);
    }

    public class Foo {
        public static void main(String[] args) {
          RunSomthing runSomthing = (number) -> {
  			  return number + 10;
          }

          runSomthing.doIt(1); // 11
          runSomthing.doIt(1); // 11
 
        }
        
    }



  • ⇒ 이를 보장하지 못하면, 함수형 프로그래밍 ❌

    • 함수 외부의 변수 사용 or 함수 외부의 값을 변경

  @FunctionalInterface
  public interface RunSomthing {
  	  int doIt(int number);
  }

  public class Foo {
    public static void main(String[] args) {
      RunSomthing runSomthing1 = new RunSomthing() {
        int baseNumber = 10;

        @Override
        public int doIt(int number) {
            baseNumber++; // 1) 외부의 값 변경
            return number + baseNumber; // 2) 외부의 값 사용
        }
      };
    }
    
  }



고차 함수 (Higher-Order Function)


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



불변성


profile
습관이 전부다.

0개의 댓글