Notice
Recent Posts
Recent Comments
Link
04-30 23:35
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

<<개발일지>>

함수형 인터페이스, 람다식 본문

Java 문법

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

개발하는지호 2024. 1. 9. 18:41

함수형 인터페이스

함수형 인터페이스란 단 하나의 추상 메서드만 선언된 인터페이스를 의미한다.

 

public interface InterFaceTest {
    int test(int a, int b);
}

 

-제약 조건

일반 인터페이스와는 다르게 함수형 인터페이스는 단 하나의 추상 메서드만 선언해야한다.

 

왜나하면, int test(int a, int b) -> a + b;와 같이 1 : 1 로 대응 되어야 하는데 두 가지로 해놓으면 불가능하기 때문이다.

 

@FunctionalInterface

개발자가 이러한 제약을 잘 준수하였는지 자바 컴파일러를 통해 확인시키기 위해서는 인터페이스 위에

@FunctionalInterface 어노테이션을 추가해주어야 한다.

 

람다식이란

 

쉽게 말해 메서드를 "하나의 식"으로 표현한 것이다.

 

하나의 식으로 표현하여 훨씬 간략하게 표현이 가능하게 되며, 메서드의 이름과 반환값이 없어지므로,

"익명함수"

라고도 한다.

 

이미지 출처:&nbsp;https://hstory0208.tistory.com/entry/Java%EC%9E%90%EB%B0%94-%EB%9E%8C%EB%8B%A4%EC%8B%9DLambda%EC%9D%B4%EB%9E%80-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%82%AC%EC%9A%A9%EB%B2%95

 

 

람다식은 언제 사용하나?

 

인터페이스가 있을 때, 굳이 재사용하지 말고 특정한 경우만 이용할때에 구현 클래스를 생성하는 것이 귀찮을 수가 있다.

 이때 우리는 익명 클래스를 사용하여 인터페이스의 추상메서드를 재정의 하게 되는데

 

class Main {
    public static void main(String[] args) {
        InterFaceTest ift = new InterFaceTest() {
            @Override
            public int test(int a, int b) {
               
                return a + b;
            }
        };

        System.out.println(ift.test(1,2)); //3
    }
}

 

이렇게 처음에 익명 구현 클래스를 작성해서 메서드를 재정의 하면, 길이가 길어지고 곧 가독성이 떨어진다.

 

그래서 이를 해결하기 위한 방법이 있는데, 바로 람다식이다.

class Main {
    public static void main(String[] args) {
        InterFaceTest ift = (a, b) -> a + b;

        System.out.println(ift.test(1, 2)); //3
    }
}

 

이렇게 함수형 인터페이스를 익명 구현 클래스로 람다식으로 사용하면 훨씬 짧은 코드를 만들 수 있다.

 

익명 함수라고도 한다.

 

활용 예시

 

우선, BookFilter 인터페이스를 만들어주고 함수형 인터페이스라는 것을 선언하는 어노테이션을 달아준다.

@FunctionalInterface
public interface BookFilter {
    boolean fileter(Books book);
}

 

 

 그런 다음 이를 활용해서 함수형 인터페이스의 객체를 매개변수를 받는 메서드 안에 넣어 그 메서드를 돌린다.


// 첫 번째 방법
BookFilter b = new BookFilter() {
            @Override
            public boolean fileter(Books book) {
               return category.equals(book.category.strip());
            }
        };
// 두 번째 방법(람다식)

BookFilter b = (book) -> category.equals(book.category.strip());


==============================================================================

    public static int getAllBooksFilterby(BookFilter filter){
        int count = 0;
        for (int i = 0; i < books.size(); i++)
            if (filter.fileter(books.get(i))) {
                count++;
                System.out.println("제목 : " + books.get(i).bookName.strip() +", 카테고리 : "
                        + books.get(i).category.strip() + ", 대출 가능 여부 : " + books.get(i).yesorno.strip());


        }
        return count;
    }

 

getAllBooksFilterby(b);

이렇게 들어가면 b 객체의 메서드를 활용해서 값을 반환한다.

 

또한,

getAllBooksFilterby((book) -> category.equals(book.category.strip()));

 

 

변수 b가

BookFilter b = (book) -> category.equals(book.category.strip());

 

이하 값을 참조하고 있기 때문이다.