Lambda Expression
람다식이란 함수를 하나의 식으로 표현한 것이다. 함수를 람다식으로 표현하면 메소드의 이름이 필요없기 때문에, 익명 함수의 한 종류라고 볼 수 있다.
// 람다 방식
(매개변수, ... ) -> { 실행문 ... }
// 예시
() -> "Hello World!";
해당 람다식을 통해 다음과 같은 장점을 얻을 수 있다.
- 불필요한 코드를 줄이고, 가독성을 높힘
- 함수를 만드는 과정없이 한번에 처리가능하여 생산성 증대
- 병렬 프로그래밍에 용이
Java에서 제공하는 함수형 인터페이스
Java에서는 자주 사용될 것 같은 함수형 인터페이스가 이미 정의되어 있다.
- Supplier<T>
매개변수 없이 반환값만 갖는 함수형 인터페이스이다. get() 함수를 이용하여 함수를 실행한다.
// 정의
@FunctionalInterface
public interface Supplier<T> {
T get();
}
// 사용 예시
Supplier<String> supplier = () -> "Hello World!";
System.out.println(supplier.get());
- Consumer<T>
객체 T를 매개변수로 받아서 사용하는 반환값이 없는 함수형 인터페이스이다. andThen과 accept 함수를 제공하고 있는데, accept함수에서 받아드린 Consumer을 먼저 처리하고 andThen으로 받은 두 번째 Consumer을 처리한다.
함수형에서 함수의 값 대인 또는 변경이 없기 때문에 첫 번째 Consumer가 split으로 데이터 변경이 일어나도, 원본 데이터는 유지가 된다.
// 정의
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
// 예시
Consumer<String> consumer = (str) -> System.out.println(str.split(" ")[0]);
consumer.andThen(System.out::println).accept("Hello World");
// 출력
Hello
Hello World
- Function<T, R>
객체 T를 매개변수로 받아서 R로 반환하는 함수형 인터페이스이다. apply()를 통해 실행시키며 Consumer와 마찬가지로 andThen()을 제공하고 있으며 추가로 compose()을 제공하고 있다.
compose는 첫 번째 함수 실행 이전에 먼저 함수를 실행하여 연쇄적으로 연결해준다.
// 정의
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
// 예시, 메소드 참조로 간소화 가능(String::length;)
Function<String, Integer> function = str -> str.length();
function.apply("Hello World");
- Predicate<T>
객체 T를 매개 변수로 받아 Boolean을 반환한다.
// 정의
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
// 예시
Predicate<String> predicate = (str) -> str.equals("Hello World");
predicate.test("Hello World");
'Programing Language > Java' 카테고리의 다른 글
Enum (0) | 2024.05.31 |
---|---|
Optional (0) | 2024.05.24 |
Stream (0) | 2024.05.09 |
Thread (수정중) (1) | 2024.05.01 |
String 객체 (0) | 2024.04.30 |