자바8 - 함수형 인터페이스과 Lambda 표현식 1

현시기얌·2021년 8월 2일
0

JAVA8

목록 보기
1/8

함수형 인터페이스

추상 메소드가 오로지 단 한 개만 있는 인터페이스다.
SAM(Single Abstract Method) 인터페이스다.
@FuncationInterface 어노테이션을 가지고 있는 인터페이스다.

public interface RunSomething {

    void doIt();

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

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

Question ) 위의 인터페이스는 함수형 인터페이스인가?

--> 정답 : 맞다

RunSomething 인터페이스는 static 메소드도 있고 default 메소드도 있지만 추상메소드는 단 한 개이기 때문에 함수형 인터페이스가 맞다.

@FunctionalInterface

JAVA에서 지원해주는 @FunctionalInterface를 이용하여 함수형 인터페이스를 나타낼 수 있다.

만약 함수형 인터페이스의 자격이 상실 하였을 경우 (예를들어 추상메소드가 2개 라던가...) @FunctionalInterface밑에 밑줄이 쳐지게 된다.

Lambda 표현식

추상 메소드를 딱 하나만 가지고 있는 인터페이스
코드를 줄일 수 있다.
메소드 매개변수, 리턴 타입, 변수로 만들어 사용 할 수도 있다.

public class Foo {


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

자바8 이전에는 함수형 인터페이스를 사용할 때 위에 처럼 익명 내부 클래스로 구현체를 만들어서 사용을 했었는데 자바8 이후부터는

public class Foo {


    public static void main(String[] args) {
        // 익명 내부 클래스 anonymous inner class
        RunSomething runSomething = () -> System.out.println("Hello");
        runSomething.doIt();
    }
}

위와 같이 함수형 인터페이스를 줄여 쓸 수 있게 되었다.
이렇게 만든 함수를 runSomething.doIt() 처럼 실행 할 수 도 있다.

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

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

이렇게 만든 람다 표현식은 Java에서 함수형 인터페이스를 Inline으로 구현한 Object로 볼 수 있는데 이런 형태가 함수 처럼 보이기 때문에 우리는 () -> System.out.println("Hello") 이런식으로 썼지만 Java라는 언어는 객체지향 언어이기 때문에 () -> System.out.println("Hello")를 변수에 할당하고 메소드의 파라미터로 전달하고 리턴타입으로 리턴할 수 있다.

순수함수 (Pure function)

  • Side effect를 만들 수 없다.(함수 밖에 있는 값을 변경하지 못한다.)
  • 상태가 없다.(함수 밖에 정의되어 있는)
    public static void main(String[] args) {
        // 익명 내부 클래스 anonymous inner class
        RunSomething runSomething = (number) -> number + 10;

        System.out.println(runSomething.doIt(1));
        System.out.println(runSomething.doIt(1));
        System.out.println(runSomething.doIt(1));
    }

위와 같이 입력 받은 값이 동일한 경우 결과 값이 모두 같아야 한다. ex) 1을 넣었으면 11이 나와야한다.
이것을 만족하지 못하면 함수형 프로그래밍으라고 부를 수 없다.

public class Foo {


    public static void main(String[] args) {
        // 익명 내부 클래스 anonymous inner class
        RunSomething runSomething = new RunSomething() {
            int baseNumber = 10;
            @Override
            public int doIt(int number) {
                return number + baseNumber;
            }
        };
    }
}

또한 위의 코드처럼 int baseNumber = 10과 같은 상태 값(함수 외부에 있는 값)을 가지고 있으면 순수 함수가 아니다.

public class Foo {


    public static void main(String[] args) {
        // 익명 내부 클래스 anonymous inner class
        RunSomething runSomething = new RunSomething() {
            int baseNumber = 10;
            @Override
            public int doIt(int number) {
                baseNumber ++;
                return number + baseNumber;
            }
        };
    }
}

위의 코드를 보면 함수 외부의 값 baseNumber의 값이 10->11->12처럼 점점 늘어나는데 이처럼 함수 외부의 값을 변경하려고 하는 경우에도 순수 함수라고 부를 수 없다.

고차 함수(High-Order function)

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

불변성

profile
현시깁니다

0개의 댓글

관련 채용 정보