일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- 테스트메소드
- ㅔㄴ션
- querydsl
- appspec.yml
- 2 > /dev/null
- 검색
- Query
- 추후정리
- 적용우선순위
- 서브쿼리
- application.yml
- ubuntu
- 외부키
- AuthenticationEntryPoint
- 메세지수정
- EC2
- appspec
- WeNews
- 커밋메세지수정
- 포트
- 테스트
- MySQL
- 참조키
- 메소드명
- 컨테이너실행
- foreignkey
- docker명령어
- 예약
- 네이티브쿼리
- subquery
- Today
- Total
제뉴어리의 모든것
[Section1][Java] 심화 - 람다 본문
람다식이란?
자바에서 함수형 프로그래밍을 지원하기 위해 사용되는 기술.
메소드를 하나의 식(expression)처럼 표현하는 것이다.
익명 함수라고도 불린다. 마치 객체가 아닌것처럼 보이기 때문이다.
쉽게 말하자면 식으로 표현된 축약된 메소드라고 할 수 있다.
결국 그냥 메소드이다.
람다식의 장점
- 코드의 간결화
- 메소드 정의하기 위해 클래스를 생성할 필요가 없음.
기존에는 어떠한 메소드를 정의하기 위해 클래스를 정의 하여야만 했다.
그러나 람다식은 클래스를 만들 필요가 없다. - 메소드의 매개변수로 메소드가 전달 가능
람다식의 특징
매개변수를 가진 메소드형태의 코드처럼 보이지만, 런타임에 익명 구현 객체를 생성
기본 람다식 코드
객체지향 프로그래밍 형식에서 기본 개념인 객체를 생성하는 부분이 없이 바로 참조 변수에 람다식을 대입하는 형태.
그렇다면 생성되는 익명 구현 객체의 타입은 어떻게 결정되는가?
참조변수 타입에따라 결정된다.
- 메소드의 기본 형태
int sum(int num1, int num2) {
return num1 + num2;
}
우선 위에 코드에서 반환형과 메소드이름을 제거한다.
(int num1, int num2) -> { // 반환타입과 메서드명 제거 + 화살표 추가
return num1 + num2;
}
그리고 반환값이 있는 메서드의 경우에는 return문과 문장 뒤에 오는 세미콜론(;)을 생략할 수 있다.
그러므로 위에 코드에서 적용을 해보자면 아래와 같다
(int num1, int num2) -> {
num1 + num2
}
그리고 메소드 바디부분에 실행문이 하나만 존재하다면 중괄호도 제거 가능하다.
아래와 같다.
(int num1, int num2) -> num1 + num2
그리고 매개변수의 타입도 유추가 가능한 경우 매개변수의 데이터 타입도 생략 가능하다.
아래와 같다.
(num1, num2) -> num1 + num2
함수형 인터페이스
람다의 대한 지금까지 설명으로는 단순히 메소드를 식으로 표현한 것이므로 익명 함수라고만 생각을 할 수 있다.
그러나 사실은 람다식은 객체이다. 즉, 이름이 없는 익명클래스 라고 할 수 있다.
함수형 인터페이스의 필요성
자바의 특징이 무엇인가
가장 대표적이고 가장 먼저 떠오르는것은 객체지향언어라는 것이다.
즉, 프로그래밍을함에 있어서 모든것이 객체인것이다.
즉, 람다식도 사용을 하려면 어떤 객체가 되어서 어떠한 변수에 담겨 있어야한다.
그럼 내가 만들고 싶은 람다식(식으로 표현된 축약된 메소드) 은 어디에 담겨야 할까?
일단 기본데이터형은 확실히 아니기 때문에 참조변수에 담겨야할 것이다.
그렇다는것은 클래스나 인터페이스 타입의 참조 변수에 담겨야 하고,
그때 필요한것이 함수형 인터페이스인것이다!
우선 람다식이란 무엇인가
그냥 메소드 하나를 축약한것이다.
그러므로 인터페이스에 메소드 하나만 정의를 해주면된다.
그리고 하나만 정의한다는것은 강제적이다.
즉, 인터페이스에 추상 메소드가 하나만 정의 된것이 함수형 인터페이스이다.
그리고 내가 정의한 람다식에 맞는 반환타입과 매개변수의 타입, 그리고 매개변수의 갯수를 알맞게 추상메소드로 정의만 해주면 된다.
함수형 인터페이스의 사용법
- 코드
public class LamdaPractice2 {
public static void main(String[] args) {
FunctionInterface functionInterface = (a, b) -> {
int sum = 0;
for (int i = a; i < b; i++) {
sum += i;
}
return sum;
};
System.out.println("functionInterface.reduce = "+ functionInterface.reduce(1, 11)); //람다식의 내용이 할당된 메소드가 reduce이기 때문에 reduce호출
}
}
interface FunctionInterface{ //함수형 인터페이스 정의
int reduce(int a, int b);
}
- 결과
functionInterface 참조 변수에 담긴것은 람다식의 방식으로 함수형 인터페이스를 재정의한 익명클래스 객체인 것이다.
자바에서 기본적으로 제공하는 함수형 메서드
마지막으로, 자바에서는 빈번하게 사용되는 함수형 인터페이스를 기본적으로 제공하고 있다.
자세히 알아보고 참조할것.
메소드 레퍼런스
메서드 참조는 람다식에서 불필요한 매개변수를 제거할 때 주로 사용한다.
즉, 람다식으로 더욱 간단해진 익명 객체를 더욱더 간단하게 사용하고 싶을때! 사용하는것이다.
메소드 레퍼런스의 필요성
람다식은 종종 기존 메서드를 단순히 호출만 하는 경우가 많다.
예를 들어 아래와 같은 람다식이 있다.
(left, right) -> Math.max(left, right);
위에 코드처럼 단순히 입력되는 매개변수를 다른 메소드에게 전달만 해주는 경우가 있다.
이럴 경우 더 간단히 코드를 축약할 수 있다.
FunctionInterface functionInterface1 = (left, right) -> Math.max(left,right); //기본적인 람다식
FunctionInterface functionInterface2 = Math::max; //기본적인 람다식을 메소드 레퍼런스형식으로 바꾼 코드
위 코드에서 Math:max 부분이 메소드 레퍼런스 형식이다.
생성자 참조
메서드 참조는 생성자 참조도 포함한다.
생성자를 참조한다는 것은 객체 생성을 의미한다. 단순히 메서드 호출로 구성된 람다식을 메서드 참조로 대치할 수 있듯이, 단순히 객체를 생성하고 리턴하도록 구성된 람다식은 생성자 참조로 대치 가능.
- 기본적인 람다식의 생성자 표현
(a,b) -> {return new 클래스(a,b);};
- 생성자 참조 로 표현된 생성자
클래스 :: new
- 생성자 참조 코드 예
//Member.java
public class Member {
private String name;
private String id;
public Member() {
System.out.println("Member() 실행");
}
public Member(String id) {
System.out.println("Member(String id) 실행");
this.id = id;
}
public Member(String name, String id) {
System.out.println("Member(String name, String id) 실행");
this.id = id;
this.name = name;
}
public String getName() {
return name;
}
public String getId() {
return id;
}
}
import java.util.function.BiFunction;
import java.util.function.Function;
public class ConstructorRef {
public static void main(String[] args) throws Exception {
Function<String, Member> function1 = Member::new;
Member member1 = function1.apply("kimcoding");
BiFunction<String, String, Member> function2 = Member::new;
Member member2 = function2.apply("kimcoding", "김코딩");
}
}
/*
Member(String id) 실행
Member(String name, String id) 실행
*/
'코드스테이츠 > 정리 블로깅' 카테고리의 다른 글
[Section1][Java] 심화 - 애너테이션 (0) | 2022.07.24 |
---|---|
[Section2] [자료구조-알고리즘] - 재귀 (0) | 2022.07.21 |
[Section1][Java] 심화 - 스레드 (0) | 2022.07.20 |
[Section1][Java] 심화 - Stream(스트림) (0) | 2022.07.19 |
[Section1][Java] 심화 - Enum (0) | 2022.07.18 |