-
함수형 인터페이스Language/Java 2023. 12. 1. 00:01
Functional Interface
java 8에서 도입된 개념으로
정확히 하나의 추상 메서드
를 가진 인터페이스를 말한다.이 함수형 인터페이스는 람다 표현식으로 잘 활용된다.
자바에는 여러가지 내장된 함수형 인터페이스가 있지만,
특히 자바 공부할 때
기능 설명 부분에서 자주 볼 수 있었던
몇 가지 인터페이스에 대해서 정리 ✏️
Function<T, R>
매개변수 :
T
Return 타입 :R
추상 메서드 :apply()
기능 : T 타입의 인자를 받으며, R 타입의 결과를 반환한다.사용 예시
기본 표현 방식 사용
public static void getLastIndex(String text) { Function<String, Integer> getBasicLastIndex = new Function<String, Integer>() { @Override public Integer apply(String s) { return s.length() - 1; } }; System.out.println( getBasicLastIndex.apply(text) ); }
람다 표현 방식 사용
public static void getLastIndex(String text) { Function<String, Integer> getLambdaLastIndex = s -> s.length() - 1; System.out.println( getLambdaLastIndex.apply(text) ); }
Function 에서 사용할 수 있는 Default 메서드
🤓✏️
Default 메서드
자바 8에서 추가된 기능으로 인터페이스에서 선언과 구현을 동시에 하는 방법이다. 인터페이스를 정의할 때 default 키워드를 사용하여 메서드를 작성하면 된다. 디폴트 메서드를 사용하면, 인터페이스에 새로운 메서드(default)를 추가하더라도 기존에 사용중이던 클래스를 수정하지 않고도 인터페이스에 추가된 메서드를 사용할 수 있다. 주의 할 부분은 여러 인터페이스에서 동일한 디폴트 메서드를 제공하는 경우 충돌이 발생할 수 있으므로 유의해서 사용해야 한다.
* andThen()
주어진 함수를 첫 번째 함수의 결과에 적용하여 새로운 자료형의 반환값을 반환한다.
f.andThen(g)
형태로 사용하며, 수학적으로 표현하면g(f(x))
와 같다.Function<Integer, Integer> f1 = num -> num * 2; Function<Integer, Integer> f2 = num -> num * num; Function<Integer, Integer> f = f1.andThen(f2); System.out.println(f.apply(3));
위에 작성한 코드를 보면 마지막 sout 문장 안에 있는 andThen 결과인 f에 3을 주었다.
3
은f1
에서 f1의 구현 내용으로 가공된 후 , 반환값이f2
에 들어가서 f2의 구현 내용에 따라 2차 가공되어 최종 반환된다.이 경우
3
->3*2
->6*6
->36
순서로 값의 변화가 일어난다.* compose()
compose()는 반대로 첫 번째 함수의 결과를 두 번째 함수에 적용한다.
f.andThen(g)
형태로 사용하며, 수학적으로 표현하면f(g(x))
와 같다.아래 부터 소개하는 인터페이스의 디폴트 메서드는 나중에 정리 😵💫
Predicate<T>
매개변수 :
T
Return 타입 :boolean
추상 메서드 :test()
기능 : T 타입의 인자를 받으며 boolean을 반환한다.사용 예시
기본 표현 방식 사용
public static void isEvenOdd() { Predicate<Integer> predicate = new Predicate<Integer>() { @Override public boolean test(Integer integer) { return integer % 2 == 0; } }; System.out.println( predicate.test(2) ? "짝수 입니다." : "홀수 입니다." ); }
람다 표현 방식 사용
public static void isEvenOdd() { Predicate<Integer> predicate2 = i -> i % 2 == 0; System.out.println( predicate2.test(3) ? "짝수 입니다." : "홀수 입니다." ); }
Consumer<T>
매개변수 :
T
Return 타입 :void
추상 메서드 :accept()
기능 : T 타입의 인자를 받으며, 아무런 결과도 반환하지 않는다.결과를 반환하지 않고 값을 사용하기만 해서 소비자인가 🙊
사용 예시
기본 표현 방식 사용
public static void print() { Consumer<String> consumer = new Consumer<String>() { @Override public void accept(String s) { System.out.printf("\"%s\" 입력 받았슴다 🤓\n", s); } }; consumer.accept("가나다라"); }
람다 표현 방식 사용
public static void print() { Consumer<String> consumer2 = s -> System.out.printf("\"%s\" 입력 받았슴다 🤓\n", s); consumer2.accept("아자차카타파하하하하하"); }
메서드 참조 표현식 사용
메서드 참조
🤓✏️ > 지금은 간단히 적어두고 나중에 추가 공부 계획자바 8에서 도입
이미 정의된 메서드를 람다 표현식 대신에 직접 참조할 수 있게 해준다.
4가지 유형의 사용 방법이 있음!
-
정적(static) 메서드 참조 :
클래스::정적메서드
ex : Integer::parseInt -
인스턴스 메서드 참조 :
인스턴스::메서드
ex : System.out::println -
비한정적 인스턴스 메서드 참조 :
클래스::메서드
ex : String::length -
생성자 참조 :
클래스::new
ex : ArrayList::new
public static void print() { Consumer<String> consumer3 = System.out::println; consumer3.accept("하하 🙈"); }
이렇게 사용하면
Consumer.accept(T t) = System.out.println(t)
이런식으로 적용 된다.Supplier<T>
매개변수 :
void
Return 타입 :T
추상 메서드 :get()
기능 : 인자를 받지 않고, T 타입의 결과를 반환한다.오, Getter()랑 같은 기능! 그러면 반대로 동작하는 Consumer.accept() 는 Setter() !! 🙊
공급자는 get() == getter() 소비자는 accept() == setter() 🙊
주로 특정
값을 생성
하거나,계산
하는데 사용된다고 한다.사용 예시
기본 표현 방식 사용
public static void getNowTime() { Supplier<LocalDateTime> supplier = new Supplier<LocalDateTime>() { @Override public LocalDateTime get() { return LocalDateTime.now(); } }; System.out.println( supplier.get() ); }
람다 표현식 사용
public static void getNowTime() { Supplier<LocalDateTime> supplier2 = () -> LocalDateTime.now(); System.out.println( supplier2.get() ); }
메서드 참조 방식 사용
public static void getNowTime() { Supplier<LocalDateTime> supplier3 = LocalDateTime::now; System.out.println( supplier3.get() ); }
UnaryOperator<T>
매개변수 :
T
Return 타입 :T
추상 메서드 :T apply(T t)
기능 : 인자로 T를 받고, T를 반환한다.Function<T, T>
를 확장한 인터페이스 이다. Function의 apply() 메서드를 그대로 사용한다. Function과 UnaryOperator의 차이점으로는 Function은 매개변수와 결과값의 자료형이 달라질 수 있고 UnaryOperator는 매개변수와 결과값의 자료형이 같아야 한다.사용 예시
기본 표현 방식 사용
public static void getPow() { UnaryOperator<Integer> uo = new UnaryOperator<Integer>() { @Override public Integer apply(Integer num) { return num * num; } }; System.out.println( uo.get() ); }
람다 표현 방식 사용
public static void getPow() { UnaryOperator<Integer> uo = num -> num * num; System.out.println( uo.get() ); }
BinaryOperator<T>
매개변수 :
T
Return 타입 :T
추상 메서드 :T apply(T t, T t)
기능 : T 타입의 인자를 2개 받고, T를 반환한다.사용 예시
기본 표현 방식 사용
public static void print(String str1, String str2) { BinaryOperator<String> bo = new BinaryOperator<String>() { @Override public String apply(String s, String s2) { return s.length() >= s2.length() ? s : s2; } }; System.out.println( bo.apply("monkey", "monday..") ); }
람다 표현 방식 사용
public static void print2(String str1, String str2) { BinaryOperator<String> bo = (s, s2) -> s.length() >= s2.length() ? s : s2; System.out.println( bo.apply("monkey", "monday..") ); }
앞으로 강의 실습 계속 하면서 새롭고 낯선 함수형 인터페이스를 만나게 되면 추가할 계획!
'Language > Java' 카테고리의 다른 글
UUID.randomUUID() (0) 2023.12.01 Stream (0) 2023.12.01 enum 클래스 (0) 2023.11.30 Optional (0) 2023.11.30 자바 메모리 모델 Java Memory Model (0) 2023.11.30 -