티스토리 뷰
Funtional Interface
- 함수형 인터페이스는 오직 하나의 추상 메서드를 지정하는 인터페이스 입니다.
- 함수형 인터페이스의 추상 메서드 시그니처를 함수 디스크립터라고 합니다.
- 쉽게는
T -> boolean, T -> R
등과 같이 메서드를 람다로 표현한 형태를 말함
- 쉽게는
- 자바 8 라이브러리 설계자 들은
java.util.function
패키지에 여러가지 함수형 인터페이스를 제공합니다.- 이번 글에서는 Predicate, Consumer, Function 인터페이스를 자세히 소개할 예정
- 첨언을 해보자면 저의 경우 실무에서 아주 유용하게 사용하고 있는 녀석입니다.
- 마치 함수 포인터를 전달하듯 클래스에 정적인 데이터가 아니라 어떠한 동작을 전달하고 싶을 때 간단하게 주입해줄 수 있는 용도로 요긴하기 쓰임 ..
Java API 함수형 인터페이스
Predicate
java.util.function.Predicate<T>
인터페이스는test
라는 추상 메서드를 정의하며 제네릭 형식 T의 객체를 인수로 받아 boolean을 반환합니다.- T 형식의 객체를 사용하는 불리언 표현식이 필요한 상황에서 Predicate 인터페이스를 사용할 수 있음
- 스트림 사용시 filter 메서드의 인자가 Predicate임
저의 경우는 Predicate를 직접 전달하는 경우는 흔치는 않았습니다.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
public <T> List<T> filter(List<T> list, Predicate<T> p) {
List<T> results = new ArrayList<>();
for (T t : list) {
if(p.test(t)) {
results.add(t);
}
}
return results;
}
Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
List<String> nonEmptyStringList = filter(stringList, nonEmptyStringPredicate);
Consumer
java.util.function.Consumer<T>
인터페이스는 제네릭 형식 T객체를 받아서 void를 반환하는accept
라는 추상 메서드를 정의합니다.- T 형식의 객체를 인수로 받아 동작을 수행하고자 할 때 사용할 수 있습니다.
- 저의 경우는 외부 컬렉션에 데이터를 추가/삭제 하고자 하는 경우 (외부 컬렉션이 바뀔 수 있는 상황)
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
public <T> void forEach(List<T> list, Consumer<T> c) {
for (T t : list) {
c.accept(t);
}
}
forEach(
Arrays.asList(1,2,3,4,5).
(Integer i) -> System.out.println(i);
)
//Collector 클래스
//myQueue가 변경될 여지가 있음
Queue<MyData> myQueue;
void setQueue(Queue<MyData> queue) {
myQueue = queue;
}
//외부 데이터 입력 클래스
Consumer<MyData> dataConsumer = (MyData data) -> myQueue.add(data);
void updateData(MyData data) {
dataConsumer.accept(data);
}
Function
java.util.function.Function<T,R>
인터페이스는 제네릭 T 를 받아 제네릭 R을 반환하는apply
추상 메서드를 정의합니다.- 일반적인 함수의 형태로 입력, 출력을 모두 매핑하는 람다를 정의할 때 사용합니다.
- Function의 경우 특정 케이스가 있다기 보다는 가장 일반적으로 많이 사용되는 것 같습니다.
- 아래 예제 처럼 데이터를 어떠한 패턴으로 변형을 시켜야 하는 경우에도 사용
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
public <T, R> List<R> map(List<T> list, Function<T, R> f) {
List<R> result = new ArrayList<>();
for (T t : list) {
result.add(f.apply(t));
}
return result;
}
List<Integer> list = map(
Arrays.asList("lambdas", "in", "action"),
(String s) -> s.length()
);
Supplier
java.util.function.Supplier<T>
인터페이스는 제니릭 T를 반환하는 추상메서드get
을 정의합니다.- 책에는 소개되지 않지만 많이 쓰여서 넣었습니다..
- 말그대로 T 형태를 출력만을 가지고 있는 공급의 역할이 주된 인터페이습니다.
- 저의 경우는 데이터를 넘겨줄 때 변경될 여지가 있는 데이터 일때 변경에 영향이 없게 하기 위하여 많이 사용하엿습니다. (예제 참고)
- 데이터를 참조하는 것이 아닌 Supplier를 이용하여 그때 그때 데이터를 공급받아 사용하는 방식
@FunctionalInterface
public interface Supplier<T> {
T get();
}
class Config {
//value..
}
class Service {
Supplier<Config> configSupplier;
public Service(Supplier<Config> configSupplier) {
this.configSupplier = configSupplier;
}
public void doSomething() {
//Config가 외부에서 변경되어도 영향이 없음
Config config = configSupplier.get();
}
}
기본형 특화
- 위 함수형 인터페이스에 Java 기본형을 사용하는 경우 어쩔 수 없이 참조형 <-> 기본형 사이 언/박싱 일어나게 됩니다.
- 기본으로 참조형인 제니릭 타입 T를 사용하기 때문
- 물론 Java에서 제공해주는 오토박싱으로 인해 문제는 없지만 이러한 변환과정에서 메모리 소비가 발생합니다.
- 그래서 Java8에서는 오토박싱을 피할 수 있도록 기본형을 사용하는 함수형 인터페이스를 제공합니다.
- IntPredicate, IntConsumer, IntFunction 등등
Java 함수형 인터페이스 정리
함수형 인터페이스 | 함수 디스크립터 | 기본형 특화 |
Predicate<T> | T -> boolean | IntPredicate, LongPredicate, Double Predicate |
Consumer<T> | T -> void | IntConsumer, LongConsumer, DoubleConsumer |
Function<T, R> | T -> R | IntFunction<R>, IntToDoubleFunction, IntToLongFunction, LongFunction<R>, LongToDoubleFunction, LontToIntFunction, DoubleFunction<R>, DoubleToIntFunction, DoubleToLongFunction, ToIntFunction<T>, ToDoubleFunction<T>, ToLongFunction<T> |
Supplier<T> | () -> T | BooleanSupplier, IntSupplier, LongSupplier, DoubleSupplier |
UnaryOperator<T> | T -> T | IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator |
BinaryOperator<T> | (T, T) -> T | IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator |
BiPredicate<L, R> | (T, U) -> boolean | |
BiConsumer<T, U> | (T, U) -> void | ObjIntConsumer<T>, ObjLongConsumer<T>, ObjDoubleConsumer<T> |
BiFunction<T, U, R> | (T, U) -> R | ToIntBiFunction<T, U> ToLongBiFunction<T, U> ToDoubleBiFunction<T, U> |
참고
반응형
'프로그래밍 > JAVA' 카테고리의 다른 글
[Java] Apache poi 엑셀 Cell 스타일링 방법 (배경, 테두리, 폰트 등) (0) | 2020.07.29 |
---|---|
[Java] 함수형 인터페이스 예외 처리 방법 (0) | 2020.07.29 |
[Java] List 일정 비율로 분할하는 방법 (0) | 2020.07.27 |
(Java) Gmail SMTP 구현시 "AuthenticationFailedException: 535-5.7.8 Username and Password not accepted" 에러 해결법 (0) | 2020.05.26 |
(Java) 장비, 시스템 메모리(RAM) 값 알아내는 방법 (feat. OSHI 라이브러리 사용법) (0) | 2020.05.07 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 이펙티브 자바
- springboot
- JavaFX Window Close
- 배낭여행
- java
- 자전거 여행
- JavaFX 종료
- 배낭 여행
- intelij
- 일본 자전거 여행
- 방통대 과제물
- 일본여행
- JavaFX
- effectivejava
- 인텔리제이
- 일본 여행
- effective java
- windows
- JavaFX 테이블뷰
- 일본 배낭여행
- JavaFX Table View
- Java UI
- 스프링부트
- 자전거
- TableView
- 이펙티브자바
- git
- 텐트
- 이펙티브
- 자바
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함