인프런 워밍업 클럽 0기 - 백엔드 코스 (과제 3)

익명 클래스와 람다식

 

람다식을 알아보기 위해서는 함수형 프로그래밍에 대해 알아보아야 한다.

 

함수형 프로그래밍은 프로그래밍의 패러다임입니다.

이전의 절차지향 프로그래밍이나 객체지향 프로그래밍과 같이 생겨난 새로운 패러다임 중 하나입니다.

함수형 프로그래밍은 자료 처리를 수학적 함수의 계산으로 취급하고 상태와 가변 데이터를 멀리하는 프로그래밍 패러다임의 하나이다.

 

프로그래밍에는 명령형 프로그래밍과 선언적 프로그래밍이 있다.

  • 명령형 프로그래밍 : 클래스에서 메서드를 정의하고, 필요할 때 그 메서드를 호출하는 것으로 명령하여 동작하는 방식

  • 선언적 프로그래밍 : 데이터가 입력으로 주어지고 데이터가 처리되는 과정을 정의하는 것으로 동작하는 방식

함수형 프로그래밍은 선언적 프로그래밍이며, 람다가 지원되기 이전까지 자바는 완전한 명령형 프로그래밍이었다.

 

함수형 프로그래밍의 조건

  • 순수 함수 : 같은 입력이 들어오면 출력 또한 같다. Side Effect가 없다.

     

  • 고차 함수 : 일급 함수의 특징을 만족해야 한다.

    • 함수의 인자로 함수를 전달할 수 있다.

    • 함수의 리턴값으로 함수를 사용할 수 있다.

  • 익명 함수 : 이름이 없는 함수(람다식)

  • 합성 함수 : 새로운 함수를 생성하거나 어떤 계산을 수행하기 위해 둘 이상의 함수를 결합하는 것(메서드 체이닝)

 

함수형 프로그래밍의 특징

  • 불변성: 함수 내에서 상태를 변경하지 않는다.

  • 참조 투명성: 프로그램 동작의 변경없이 관련 값을 대체할 수 있다

  • 일급 함수 : 함수를 함수의 매개변수로, 함수의 반환값으로, 변수나 자료구조에 담을 수 있다.

  • 게으른 평가 : 값이 필요한 시점에 평가한다.(람다식을 사용한 스트림에서 종단연산이 없다면 아직 값을 연산하지 않는다.)

 

람다식은 메서드를 하나의 식으로 표현하는 선언적 프로그래밍의 방법이다.

이전에는 익명 클래스를 이용하여 익명 구현 객체를 사용할 수 있었다.

 

람다식의 특징

  • 메서드의 이름이 없다.

  • 어떠한 클래스에 종속되지 않은 함수이다.

  • 일급 시민이다.

 

람다식 사용법

(int a1,int a2) -> {return a1+a2;}
(int a1,int a2) -> a1+a2;
(int a1) -> System.out.println(a1);
a1 -> System.out.println(a1);

 

익명 클래스

  • 하나의 메서드만을 사용할 클래스라면 익명 클래스로 정의해 해당 메서드만 익명 클래스 내부에 선언하여 사용할 수 있도록 했다.

public static void main(String[] args) {
        Comparator<Integer> comp = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2); 
            }				
        };

        System.out.println(comp.compare(2, 1));
    }

 

함수형 인터페이스

함수형 인터페이스는 제너릭 타입을 타입 파라미터로 가진다. 인터페이스에 정의된 하나의 추상 메서드는 함수형 인터페이스의 구현체인 람다함수를 실행시킬 메서드가 된다.

  • 추상 메서드가 무조건 한개만 존재해야 한다.

  • @FunctionalInterface 어노테이션을 통해 검증할 수 있다.

  • java.util.function에 빌트인 함수형 인터페이스가 존재한다.

  • 필요한 경우 구현해서 사용할 수도 있다.

함수형 인터페이스의 활용 방법 : https://bcp0109.tistory.com/313

 

람다식 vs 익명 클래스

  • 람다는 메서드로 생성된다. 익명 클래스는 새로운 클래스 파일이 생성된다.

  • 익명 클래스의 this는 해당 클래스를 가리키고, 람다의 this는 람다가 포함된 클래스를 가리킨다.

 

메소드 레퍼런스

람다 표현식을 더 간단하게 표현하는 방법

람다 표현식으로 표현할 경우

Consumer<String> func = text -> System.out.println(text);
func.accept("Hello");

메소드 레퍼런스로 표현할 경우

Consumer<String> func = System.out::println;
func.accept("Hello");
  • ClassName::MethodName 형식으로 입력한다.

  • stream()에서 람다식을 활용하지 않고 메서드 레퍼런스로 표현식을 더 간단하게 해줄 수 있습니다.

 

 

Reference

댓글을 작성해보세요.

채널톡 아이콘