평범한 연구소

[Java] 람다식 본문

JAVA

[Java] 람다식

soyeonisgood 2023. 2. 16. 20:19

람다식

  • 람다식이란 ?
    • 메소드를 하나의 식으로 표현한 것으로 익명함수 라고도 함
    • 메소드의 매개변수로 전달 가능, 메소드를 결과로 반환도 가능
    • 원래 자바는 익명 클래스를 이용하여 익명 구현 객체를 사용했음. 이를 함수형 프로그래밍을 도입하면서 간단하게 표현할 수 있는 방법이 람다식 !
      • 람다식은 함수형 인터페이스에 접근하여 사용된다.
    • 보통의 메소드가 아닌, 함수이다
      • 메소드: 클래스의 종속적
      • 함수: 어느 곳에도 종속적이지 않음
    • 1급 객체이므로 Stream API 매개변수로 전달 가능
    • final이 붙지 않아도 상수로 간주된다
    • 익명 클래스 객체와 동등함
  • 람다식의 장단점
    • 장점
      • 불필요한 코드를 제거하여 간결해짐
      • 코드가 간결해지고 개발자의 의도가 명확하게 드러나므로 가독성 향상
      • 함수를 만드는 과정 없이 한 번에 처리할 수 있어서 코딩 시간 단축
      • 다중 cpu를 활용하는 형태로 구현되어 있어 병렬 처리에 유리
    • 단점
      • 람다를 사용해서 만든 익명함수는 재사용 불가
      • 디버깅 시 함수 콜스택 추적이 어려움
      • 재귀로 만들어 완전탐색하는 경우, 느릴 수 있음
      • 람다식을 남발하면 오히려 가독성 떨어짐
  • 함수형 인터페이스란 ?
    • Java는 일반 함수와 순수 함수를 다르게 취급. 이를 구분하기 위해 함수형 인터페이스가 등장함
    • 추상 메소드가 오직 하나면 함수형 인터페이스
      • 이 추상 메소드는 이후 함수형 인터페이스의 구현체인 람다 함수를 실행시킬 메소드
      • default, static 메소드는 개수에 제약 없음
    • @FuntionalInterface 어노테이션 사용
      • 해당 인터페이스가 함수형 인터페이스인지 검사
      • 없이도 동작에 문제는 없지만, 검증과 유지보수를 위해 사용하는 게 좋음
    • 함수형 인터페이스는 람다식으로 표현 가능
    • 제네릭 <T> 을 타입 파라미터로 가진다
  • 함수형 인터페이스과 람다식
    • 람다식이 함수형 인터페이스를 반환하므로, 함수형 인터페이스를 사용
      • 즉, 람다식을 다루기 위한 인터페이스
      • 람다식을 하나의 변수로 대입할 때 사용하는 참조 변수 타입을 함수형 인터페이스라고 부른다
    • 변수처럼 메소드를 주고 받는 것 가능
    • 함수형 인터페이스로 람다식을 참조할 수 있는 것. 람다식의 타입이 함수형 인터페이스 타입과 일치하는 것은 아님.
      • 람다식은 익명 객체, 익명 객체는 컴파일러가 이름을 정하기 때문에 타입을 알 수 없음.
    • 람다식은 오직 함수형 인터페이스로만 형변환 가능 !
    public class LambdaEx2 {
        public static void main(String[] args) {
            MyFunction f = () -> {};
            Object obj = (MyFunction)(() -> {}); // Object 타입으로 형변환 생략됨
            String str = ((Object)(MyFunction) (() -> {})).toString();
        }
    }
    
    package pratice.lambda;
    
    @FunctionalInterface
    interface MyFunction2 {
        void myMethod();
    }
    
    class Outer {
        int val = 10;
    
        class Inner {
            int val = 20;
    
            void method(int i) {
                int val = 30;
    
                MyFunction2 f = () -> {
                    System.out.println("i : " + i);
                    System.out.println("val: "+ val);
                    System.out.println("this.val: " + this.val);
                    System.out.println("Outer.this.val: " + Outer.this.val);
                };
    
                f.myMethod();
            }
        }
    }
    
    public class LambdaEx3 {
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner inner = outer.new Inner();
            inner.method(100);
        }
    }
    
    • java.util.function 패키지
    • 생성자의 메소드 참조
      • () → new MyClass() = MyClass::new
      • x → new int[x] = int[]::new
      • element → element.getName() = Member::getName()
        • 인스턴스 → 인스턴스.메소드명
        • 인스턴스의 클래스명::메소드명

'JAVA' 카테고리의 다른 글

[Spring] 엔티티와 is~() (자바빈 규약)  (0) 2023.03.14
[Docker] 기본 명령어  (0) 2023.02.23
[Java] Thread 쓰레드  (0) 2023.02.13
[백준] 1235번: 학생 번호 (JAVA)  (0) 2023.02.10
[Java] this와 this()  (0) 2023.02.10