[STUDY] 240320 | Lambda | 함수형 인터페이스①

Nimgnos·2024년 4월 16일
0

👾 STUDY

목록 보기
37/40
post-thumbnail

💻 Lambda(람다)

  • 람다 함수는 함수형 프로그래밍에서 중요한 개념 중 하나로, 익명 함수(anonymous function)라고도 함.
  • 이름이 없는 함수로, 일반적으로 함수를 한 번만 사용하거나 함수를 인자로 전달해야 하는 경우에 유용하게 사용됨.

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

  • 자바 8부터 도입된 개념으로, 이름 그대로 "함수"를 위한 인터페이스
    ➡️ 이 인터페이스를 구현한 클래스는 하나의 함수 처럼 동작하게 됨.
  • 예) Function<T, R> 이라는 함수형 인터페이스는 T라는 타입을 입력 받아 R이라는 타입의 출력
    ➡️ 함수형 인터페이스를 구현한 클래스는 T라는 타입의 입력을 받아 R이라는 타입을 반환하게 됨

💡 함수형 인터페이스 종류 / 특징

  • 함수형 인터페이스는 크게 5가지로 Consumer, Supplier, Function, Operator, Predicate가 있음.
  • 함수형 인터페이스의 특징으로는 각각 한개의 추상 메서드만을 갖고 있다는 특징이 있음.

🤓 예제


📌 인터페이스

//인터페이스 -> 익명 이너 클래스 -> 람다
 interface Printable{ //인터페이스는 단독 사용 불가
    void print();
 }
 class MyPrinter implements Printable{ //인터페이스를 구현하는 클래스 , 오버라이드
     public void print() {
         System.out.println("안녕하세요.");
     }
 }
public class Anonymous {
    public static void main(String[] args) {
        //Printable 인터페이스의 print() 메소드 호출
        //호출 결과 '안녕하세요' 출력
        Printable p = new MyPrinter();
        p.print();
        //익명 이너 클래스
        Printable p1 = new Printable() {
            @Override
            public void print() {
                System.out.println(111);
            }
        };
        p1.print(); ///111
    }

📌 함수형 인터페이스(Functional Interface) 예제(1)

  • 람다식으로 변형할 수 있고 사용 빈도가 높음
  • 람다식에서 메소드 내용이 한 줄이면 { } 삭제 가능
//함수형 인터페이스(Functional Interface)
//람다식으로 변형할 수 있고 사용 빈도가 높음
interface GetNum{
    void get(int num1, int num2);
}
class GetSum implements GetNum{
    public void get(int num1, int num2){
        System.out.println(num1 + num2);
    }
}
class GetSub implements GetNum{
    public void get(int num1, int num2){
        System.out.println(num1 - num2);
    }
}
public class Anonymous2 {
    public static void main(String[] args) {
        GetNum n1 = new GetSum();
        n1.get(10, 20);
        GetNum n2 = new GetSub();
        n2.get(20, 10);
 //////////////////////////////////////////////
        GetNum n3 = new GetNum() {
            @Override
            public void get(int num1, int num2) {
                System.out.println(num1 + num2);
            }
        };
        n3.get(10, 20);
        GetNum n4 = new GetNum() {
            @Override
            public void get(int num1, int num2) {
                System.out.println(num1 - num2);
            }
        };
        n4.get(10, 20);   ///////////////////////////////////////////////////
        //람다
        //메소드 내용이 한 줄이면 { } 삭제 가능

        Printable p2 = () ->
                System.out.println(111);

        ///////////////////////////////////
//        GetNum n5 = new GetNum() {
//            @Override
//            public void get(int num1, int num2) {
//                System.out.println(num1 + num2);
//            }
//        };
//        n3.get(10, 20);
        GetNum n5 = (num1, num2) -> System.out.println(num1 + num2);
        n5.get(20, 10);
        //람다식 이용해서 get 메소드의 내용을 매개변수로 들어온
        //두 수의 곱을 출럭
        GetNum n6 = ((num1, num2) -> System.out.println(num1 * num2));
        n6.get(20, 10);
    }
}

📌 함수형 인터페이스(Functional Interface) 예제(2)

Predicate<T>

  • java.util.function.Predicate 인터페이스는 test 메소드를 추상 메소드로 선언한 함수형 인터페이스
  • 한 개의 입력을 받아서 boolean 결과를 반환하는 함수를 정의
  • boolean test(T t) 메서드를 가지며, 이 메서드는 매개변수 T를 받아서 boolean 결과를 반환함.
  • 주로 객체를 조건에 따른 필터링이 필요할 때 사용한다.
interface Predict{ //예측
    boolean test(int num);
}
//interface Predicate<T>{ //예측
//    boolean test(Integer t);
//}
//매개변수로 들어온 수가 짝수 일때만 true 리턴
//매개변수로 들어온 수가 10보다 작으면 true 리턴
//매개변수로 들어온 수가 10이면 true 리턴
public class ExampleLambda {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        //배열 -> 리스트: 리스트는 안의 내용 수정 불가
        List<Integer> list = Arrays.asList(arr);
        List<Integer> list1 = new ArrayList<>(list);
        //리스트 내 정수 중 5보다 작은 수를 지우기
        Predicate<Integer> p = num -> num < 5;
        list1.removeIf(p);
        list1.forEach(num -> System.out.println(num));
        //리스트에 저장된 수 중 짝수 합을 출력
        Predict p1 = num -> num % 2 == 0;
        lambda(list, p1);
        // ==
        lambda(list, num -> num % 2 == 0);
        //
        lambda(list, num -> num % 2 != 0);
        lambda(list, num -> num > 5); //리스트에 있는 숫자 하나 하나 비교해서 5보다 클 때 리턴
    }
    public static void lambda(List<Integer> list, Predict p){
        int sum = 0;
        //조건을 만족한 숫자는 짝수로만 걸러짐
        for(int e : list){
            if(p.test(e)){
                sum = sum + e;
            }
        }
        System.out.println(sum);
    }
}

📌 람다(lambda) 예제

  • Basic b = ( ) -> { }
    ( 메소드의 매개변수 ) -> { 메소드의 내용부 }
  • 매개변수가 없어도 매개변수의 자리 ( )는 남겨둬야함
  • 매개변수가 1개일 때는 소괄호( ) 생략 가능
  • 1개 문장이어도 리턴 문장이면 중괄호{ } 생략 불가
  • 메소드 구현부의 마지막 코드 결과가 값일 때는 자동으로 리턴으로 간주 ('return' 생략 가능)
interface Basic{
    void print();
}
interface PrintMSG{
    void print(String msg);
}
interface Calculator{
    int cal(int a, int b);
}
public class Lambda1 {
    public static void main(String[] args) {
        //1. Basic 인터페이스의 print() 메서드를
        //람다식을 사용하여 "java"라는 출력 기능을 구현하고
        //구현한 람다식을 사용하시오.
        //Basic b = () -> {} 
        //Basic b = 메소드의 매개변수 -> 메소드의 내용부
        //* 매개변수가 없어도 매개변수의 자리는 남겨둬야함 ()
        Basic b = () -> System.out.println("java");
        b.print();
        //2. printMsg의 인터페이스의 print() 메서드를 람다식으로
        //구현하여 매개변수로 전달될 문자열을 출력하는 기능구현 및 호출
        //* 매개변수가 1개일 때 소괄호 생략 가능
        PrintMSG p = s -> System.out.println(s);
        p.print("java");
        //3. 매개변수로 들어온 수의 합을 리턴
        // 1개 문장이어도 리턴 문장이면 { 중괄호 생략 불가 }
        Calculator c1 = (num1, num2) -> {return num1 + num2;}; // {} 지우면 오류
        // 대신 다른 함축적 문법 제공
        // 이 문법을 사용하면 중괄호도 생략 가능
        // 메소드 구현부의 마지막 코드 결과가 값일 때는 자동으로 리턴으로 간주 ('return' 생략 가능)
        Calculator c2 = (num1, num2) -> num1 + num2;
    }
}

🔍 참조

profile
먹고 기도하고 코딩하라

0개의 댓글