JAVA/Modern JAVA

[JAVA 8] 함수형(Functional) 인터페이스 와 람다(Lambda)표현식

빅콜팝 2022. 10. 12. 14:02
728x90
반응형

함수형(Functional) 인터페이스 와 람다(Lambda)표현식


- 함수형 인터페이스는 추상 메소드가 오직 하나인 인터페이스를 말한다. (defult method 또는 static method는 여러개 존재해도 된다.)
- @FunctionalInterface 어노테이션을 사용한다. -> 해당 인터페이스가 함수형 인터페이스 조건에 맞는지 검사해준다. (인터페이스 검증 및 유지보수를 위해 붙여주는 것이 좋다.)
- 자바의 람다식은 함수형 인터페이스로만 접근이 가능하다

=> 이러한 함수형 인터페이스를 사용하는 이유는 람다식을 사용하기 위함이고, 람다식을 사용 하는 이유는 불필요한 코드를 줄이고, 가독성을 높이기 위함이다.

@FunctionalInterface
public interface FunctionalInterface {
    public abstract void print(String text);
}

FunctionalInterface func = text -> System.out.println(text);
func.print("hi FunctionalInterface");

// 출력 값 : hi FunctionalInterface

 


✅ JAVA에서 기본적으로 제공하는 Functional Interface

함수형 인터페이스 Descripter Method
Predicate T -> boolean boolean test(T t)
Consumer T -> void void accept(T t)
Supplier ( ) -> T T get()
Function<T,R> T -> R R apply(T t)
Comparator (T, T) -> int int compare(T o1, T o2)
Runnable ( ) -> void void run()
Callable ( ) -> T V call()

이 외에 함수형 인터페이스 java.util.function

 

 

 Predicate 

: 인자를 하나 받아서 boolean 타입을 리턴한다.
람다식으로는 T -> boolean 로 표현한다..

@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}

// T -> boolean 
Predicate<String> startsWithKim = s -> s.startsWith("kim");
System.out.println(startsWithKim.test("kimHappy"));

// 출력값 : true

 

 

Consumer

: 인자 하나를 받고 아무것도 리턴하지 않는다.
람다식으로는 T -> void 로 표현한다.

@FunctionalInterface
public interface Consumer<T> {
    void accept(T t);
}

// T -> void
Consumer<String> printString = text -> System.out.println("hi " + text);
printString.accept("Consumer");

// 결과 값 : hi Consumer

 

 

Supplier

: 아무런 인자를 받지 않고 T 타입의 객체를 리턴한다.
람다식으로는 ( ) -> T 로 표현한다.

@FunctionalInterface
public interface Supplier<T> {
    T get();
}


// ( ) -> T
Supplier<String> getString = () -> "hi Supplier!";
String str = getString.get();
System.out.println(str);

// 결과값 : hi Supplier!

 

 

Function

: T 타입 인자를 받아서 R 타입을 리턴한다.
람다식으로는 T -> R 로 표현한다.

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

// T -> R 
Function<Integer, Integer> multiply = value -> value * 2;
Integer result = multiply.apply(3);
System.out.println(result);

// 결과값 : 6

 

 

Comparator

: T 타입 인자 두개를 받아서 int 타입을 리턴한다.
람다식으로는 (T, T) -> int 로 표현한다.

@FunctionalInterface
public interface Comparator<T> {
    int compare(T o1, T o2);
}

// (T, T) -> int
Comparator<Integer> numAdd = (num1, num2) -> num1 + num2;
System.out.println(numAdd.compare(10,20));

// 출력값 : 30

 

 

Runnable

: 아무런 객체를 받지 않고 리턴도 하지 않는다.
람다식으로는 ( ) -> void 로 표현한다.

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

// 람다식 : ( ) -> void
Runnable runnable = () -> System.out.println("hi runnable!");
runnable.run();

 

 

Callable

: 아무런 인자를 받지 않고 T 타입 객체를 리턴한다.
람다식으로는 ( ) -> T 로 표현한다.

@FunctionalInterface
public interface Callable<V> {
    V call() throws Exception;
}

// ( ) -> T
Callable<String> stringCallable = () -> "hi Colllable";
System.out.println(stringCallable.call());

// 출력값 : hi Colllable

 

 

Callable VS Supplier

: 아무런 인자를 받지 않고 T 타입 객체를 리턴한다.

둘의 차이는 Callable는 결과를 반환하고 예외를 throw할 수 있고, 다른 스레드에 의해 인스턴스가 잠재적으로 실행되는 클래스를 위해 설계 되었다. 반면 Supplier는 그저 값은 제공하는 기능을 한다.
=> 다른 스레드를 처리하지 않거나 작업에서 예외가 발생할 가능성이 매우 낮은 경우 외에는 Callable 사용을 권장한다.

728x90
반응형