🔍 람다식
- 자바 8에 추가된 가장 큰 특징이다.
- 자바가 "함수형" 프로그래밍 형태를 받아들인 결과이다.
✍ 함수형 프로그래밍
- 함수형: 1950년대, 객체지향: 1990년대
- 기능 위주의 프로그래밍 기법
- 객체지향: 클래스에 속성과 기능을 정의
- 함수형: 기능. 즉, 함수가 따로 존재
✍ 함수형 프로그래밍 특징
1. 순수함수: 동일한 input에는 동일한 output이 나와야 하며 (동적바인딩) side-effect가 없는 함수를 뜻한다
(참조변수, 원본데이터 수정 x)
=> 외부의 상태를 변경하거나 외부의 값을 참조하지 않는다
2. 1급함수 : 함수가 매개변수로 전달 가능. 함수가 리턴이 될 수 있음. 함수를 변수에 저장 가능.
✍ 람다식 기본 문법
() -> { }
(데이터타입 매개변수, ...) -> {실행문, ...}
1. 기본형
(int x) -> {System.out.println(x);}
2. 매개변수의 타입을 추론할 수 있는 경우에는 데이터 타입 생략이 가능하다.
(x) -> {System.out.println(x);}
3. 매개변수나 실행문이 하나라면 소괄호()와 중괄호{}를 생략할 수 있다. 단, 이때 세미콜론은 생략한다.
x -> System.out.println(x)
4. 매개변수가 없을 경우에는 소괄호()를 사용한다. 생략이 불가능하다.
(x) -> System.out.println(x)
5. 리턴이 필요한 경우 return 키워드를 사용한다.
(x, y) -> {return x + y;}
6. 실행문이 단순히 return문 하나로 표현되는 경우엔 표현식만 사용할 수 있으며,
이때 리턴 값을 표현식의 결과값이 된다. 주의! 이때 세미콜론은 생략한다.
(x, y) -> x + y
String[] str = {"this", "is", "java", "world"};
System.out.println(Arrays.toString(str));
=> 이런 문자열 배열이 있다고 가정하다. 배열을 출력하면
이렇게 출력된다.
이 배열을 정렬하기 위해 익명클래스와 람다식을 사용해보자.
Arrays.sort(str, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2) * -1;
}
});
정렬을 위해 Comparator 인터페이스를 사용하였다. 인터페이스를 사용하기 위해서는 반드시 메서드 오버라이딩을 통해 추상메서드를 구현해야 한다. 그래서 compare() 메서드를 오버라이딩 하였다.
두 문자열을 비교 후 음수를 곱하여 내림차순으로 정렬하고자 한다.
위 코드를 람다식으로 표현하면
Arrays.sort(str, (String o1, String o2) -> {
return o1.compareTo(o2) * -1;
});
Arrays.sort(str, (o1, o2) -> {
return o1.compareTo(o2) * -1;
});
=> 우선 두 문장은 모두 동일한 내용을 표현한다. 람다식 사용 시, 매개변수 타입을 추론할 수 있는 경우 데이터 타입을 명시하지 않아도 괜찮다. 그렇게 때문에 위의 코드에선 String을 명시하였지만, 아래 코드에서는 생략하였다.
이를 좀 더 간결하게 고칠 수 있다.
Arrays.sort(str, (o1, o2) -> o1.compareTo(o2) * -1);
=> 실행문이 단순히 return문 하나로 표현되는 경우에 리턴 키워드 생략이 가능하다. 이때 리턴 값은 표현식의 결과값이 된다. 세미콜론은 생략한다.
=> 내림차순 정렬되었다.
🔍 람다식 사용의 장점과 단점
✍ 장점
1. 코드의 간결성
- 기본적으로 "익명 내부클래스" 형태보다 간결하다.
- 실행문이 간단할 경우 그 효과가 더욱 부각된다.
그렇기 때문에 가독성이 높아, 어떤 로직인지 바로 알아보기가 편하다.
2. 지연 연산을 이용하여 향상된 퍼포먼스를 보여줄 수 있다.
- 연산은 나중으로 미루어 두었다가 한꺼번에 연산하는 방식
- 메모리상의 효율성 및 불필요한 연산은 배제가 가능하다.
✍ 단점
1. 모든 원소를 순회하는 경우 어떤 방법으로 작성하더라도 람다식이 조금 느릴수밖에 없다.
(최종 출력되는 bytecode는 단순 반복문보다 몇 단계를 더 거칠 수 밖에 없다.)
2. 디버깅 시 추적이 매우 어렵다.
거의 불가능에 가깝다고 봐야한다. 그래서 람다식으로 작성한 로직은 간단하며, 완벽해야한다.
3. 랍다식이 남용되면 가독성이 떨어지기 때문에 오히려 코드를 이해하기 어려워질 수 있다.
'개발 > Java' 카테고리의 다른 글
[Java] BigInteger, BigDecimal 클래스 (0) | 2023.03.20 |
---|---|
[Java] 스트림(Stream) (0) | 2023.03.15 |
[Java] StringBuilder & StringBuffer (0) | 2023.03.11 |
[Java] Thread = 쓰레드 (0) | 2023.03.11 |
[Java] 제네릭 타입의 상속과 구현 (0) | 2023.03.11 |