인프런 워밍업 클럽 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
댓글을 작성해보세요.