람다
람다식
💡 함수(메서드)를 간단한 식으로 표현하는 방법
작성법
- 메서드의 이름과 반환타입 제거 후 {} 앞에 → 추가
- 간단 규칙
- return 키워드 생략 가능 (문장 끝 ; 생략)
- 파라미터 타입 추론 가능하면 생략 (대부분 경우)
- 매개변수 1개 → () 생략 가능 (파라미터 타입이 있다면 생략 불가)
- 블록 안에 문장이 1개 → {} 생략 가능 (문장 끝 ; 생략)
익명 객체
람다식은 익명 함수가 아니라 익명 객체이다.
(자바는 메서드만 존재할 수 있기 때문에 익명 클래스 안에 메서드로 존재하게 됨)
(a, b) -> a > b ? a : b // 객체
- 익명 객체
- → 객체의 선언과 생성이 동시에 이루어짐
new Object() {
int max(int a, int b){
return a > b ? a : b;
}
}
- 람다식(익명 객체)를 다루기 위한 참조변수가 필요. 참조변수의 타입은?
- 이 문제를 해결하기 위해 **‘함수형 인터페이스’**가 등장
- Object obj = new Object() { int max(int a, int b){ return a > b ? a : b; } } 타입 obj =(a, b) -> a > b ? a : b // 어떤 타입? // 만약 Object 타입으로 하게 되면 int value = obj.max(3, 5); // **에러. Object 클래스에 max()가 없음**
함수형 인터페이스
💡 단 하나의 추상 메서드만 선언된 인터페이스
@FunctionalInterface
interface MyFunction {
public abstract int max(int a, int b);
}
// 익명 클래스 (클래스의 선언, 객체 생성을 동시에)
MyFunction f = new MyFunction(){
public int max(int a, int b){
return a > b ? a : b;
}
};
int value = f.max(3, 5); // OK
람다식(익명 객체)을 다루기 위한 참조변수의 타입은 함수형 인터페이스로 한다.
(단, 함수형 인터페이스의 메서드와 람다식의 매개변수 개수와 반환타입이 일치해야 함)
MyFunction f = (a, b) -> a > b ? a : b;
즉, 함수 인터페이스는 람다표현식을 다루기 위해서 사용함
예시
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
Collections.sort(list, new Comparator<String>() {
public int compare (String s1, String s2) {
return s2.compareTo(s1);
}
});
@FunctionalInterface
interface Comparator<T>{
int compare(T o1, T o2);
}
List<String> list = Arrays.asList("abc", "aaa", "bbb", "ddd", "aaa");
Collections.sort(list, (s1, s2) -> s2.compareTo(s1));
함수형 인터페이스 타입의 매개변수, 반환타입
- 추후 정리
java.util.function 패키지
- 자주 사용되는 다양한 함수형 인터페이스 제공
Predicate<T>
Predicate<String> isEmptyStr = s -> s.length() == 0;
String s = "";
if(isEmptyStr.test(s){
System.out.println("This is an empty string.");
}
스트림(Stream)
💡 다양한 데이터 소스(배열, 컬렉션)를 표준화된 방법으로 다루기 위한 것
- JDK 1.8 이전까지 배열과 각 컬렉션마다 서로 다른 처리 로직을 가지고 있었음
- Stream이 나오면서 모든 데이터 소스(배열, 컬렉션)는 Stream으로 변환할 수 있게 되었고 같은 코드로 원하는 연산이 될 수 있게 표준화됨
스트림 작업 순서⭐️
- 스트림 만들기
- 중간 연산 (0~n 번)
- 최종 연산 (1번)
- 결과
스트림 만들기
- 컬렉션 : Stream<T> Collection stream();
- 배열 : Stream.of();
- 람다식
// 컬렉션
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> intStream = list.stream();
// 배열
Stream<String> strStream = Stream.of(new String[]{"a", "b", "c"});
// 람다식
Stream<Integer> evenStream.= Stream.iterate(0, n -> n+2);
Stream<Double> randomStream = Stream.generate(Math::random);
중간 연산과 최종 연산
- 중간 연산 - 연산결과가 스트림인 연산. 반복적으로 적용 가능
- 최종 연산 - 연산결과가 스트림이 아닌 연산. 단 한 번만 적용 가능(스트림의 요소를 소모)
특징
- 스트림은 데이터 소스로부터 데이터를 읽기만 할 뿐 변경하지 않는다. ( Read Only - 원본 변경 X )
- 스트림은 Iterator처럼 일회용이다.(필요하면 다시 스트림을 생성해야 함)
- 최종 연산 전까지 중간연산이 수행되지 않는다. - 지연된 연산
- 스트림은 작업을 내부 반복으로 처리 ( 성능은 낮아질 수 있어도 코드 간결 )
- 스트림의 작업을 병렬로 처리 - 병렬스트림 (parallel())
'Spring 단기심화 2기' 카테고리의 다른 글
TIL_Transaction_241122 (0) | 2024.11.22 |
---|---|
TIL_JWT_241121 (1) | 2024.11.21 |
TIL_Spring 예외 처리_241115 (2) | 2024.11.15 |
TIL_MSA 들어가기_241114 (0) | 2024.11.14 |
TIL _ 브랜지 Merge 전략 _ 241112(화) (0) | 2024.11.12 |